OSDN Git Service

resolve merge conflicts of f7388e6 to nyc-dev
[android-x86/system-bt.git] / btif / src / btif_rc.c
1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 /*****************************************************************************
18  *
19  *  Filename:      btif_rc.c
20  *
21  *  Description:   Bluetooth AVRC implementation
22  *
23  *****************************************************************************/
24
25 #define LOG_TAG "bt_btif_avrc"
26
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <pthread.h>
30 #include <string.h>
31 #include <time.h>
32 #include <unistd.h>
33
34 #include <hardware/bluetooth.h>
35 #include <hardware/bt_rc.h>
36
37 #include "avrc_defs.h"
38 #include "bta_api.h"
39 #include "bta_av_api.h"
40 #include "btif_av.h"
41 #include "btif_common.h"
42 #include "btif_util.h"
43 #include "bt_common.h"
44 #include "device/include/interop.h"
45 #include "uinput.h"
46 #include "bdaddr.h"
47 #include "osi/include/list.h"
48 #include "osi/include/properties.h"
49 #include "btu.h"
50 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
51
52 /*****************************************************************************
53 **  Constants & Macros
54 ******************************************************************************/
55
56 /* cod value for Headsets */
57 #define COD_AV_HEADSETS        0x0404
58 /* for AVRC 1.4 need to change this */
59 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
60
61 #define IDX_GET_PLAY_STATUS_RSP   0
62 #define IDX_LIST_APP_ATTR_RSP     1
63 #define IDX_LIST_APP_VALUE_RSP    2
64 #define IDX_GET_CURR_APP_VAL_RSP  3
65 #define IDX_SET_APP_VAL_RSP       4
66 #define IDX_GET_APP_ATTR_TXT_RSP  5
67 #define IDX_GET_APP_VAL_TXT_RSP   6
68 #define IDX_GET_ELEMENT_ATTR_RSP  7
69 #define MAX_VOLUME 128
70 #define MAX_LABEL 16
71 #define MAX_TRANSACTIONS_PER_SESSION 16
72 #define MAX_CMD_QUEUE_LEN 8
73 #define PLAY_STATUS_PLAYING 1
74
75 #define CHECK_RC_CONNECTED                                                                  \
76     BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__);                                            \
77     if (btif_rc_cb.rc_connected == FALSE)                                                    \
78     {                                                                                       \
79         BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
80         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     {                                                                                          \
94         BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
95         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 }
103
104 /*****************************************************************************
105 **  Local type definitions
106 ******************************************************************************/
107 typedef struct {
108     UINT8 bNotify;
109     UINT8 label;
110 } btif_rc_reg_notifications_t;
111
112 typedef struct
113 {
114     UINT8   label;
115     UINT8   ctype;
116     BOOLEAN is_rsp_pending;
117 } btif_rc_cmd_ctxt_t;
118
119 /* 2 second timeout to get interim response */
120 #define BTIF_TIMEOUT_RC_INTERIM_RSP_MS     (2 * 1000)
121 #define BTIF_TIMEOUT_RC_STATUS_CMD_MS      (2 * 1000)
122 #define BTIF_TIMEOUT_RC_CONTROL_CMD_MS     (2 * 1000)
123
124
125 typedef enum
126 {
127     eNOT_REGISTERED,
128     eREGISTERED,
129     eINTERIM
130 } btif_rc_nfn_reg_status_t;
131
132 typedef struct {
133     UINT8                       event_id;
134     UINT8                       label;
135     btif_rc_nfn_reg_status_t    status;
136 } btif_rc_supported_event_t;
137
138 #define BTIF_RC_STS_TIMEOUT     0xFE
139 typedef struct {
140     UINT8   label;
141     UINT8   pdu_id;
142 } btif_rc_status_cmd_timer_t;
143
144 typedef struct {
145     UINT8   label;
146     UINT8   pdu_id;
147 } btif_rc_control_cmd_timer_t;
148
149 typedef struct {
150     union {
151         btif_rc_status_cmd_timer_t rc_status_cmd;
152         btif_rc_control_cmd_timer_t rc_control_cmd;
153     };
154 } btif_rc_timer_context_t;
155
156 typedef struct {
157     BOOLEAN  query_started;
158     UINT8 num_attrs;
159     UINT8 num_ext_attrs;
160
161     UINT8 attr_index;
162     UINT8 ext_attr_index;
163     UINT8 ext_val_index;
164     btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
165     btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
166 } btif_rc_player_app_settings_t;
167
168 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
169 typedef struct {
170     BOOLEAN                     rc_connected;
171     UINT8                       rc_handle;
172     tBTA_AV_FEAT                rc_features;
173     BD_ADDR                     rc_addr;
174     UINT16                      rc_pending_play;
175     btif_rc_cmd_ctxt_t          rc_pdu_info[MAX_CMD_QUEUE_LEN];
176     btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
177     unsigned int                rc_volume;
178     uint8_t                     rc_vol_label;
179     list_t                      *rc_supported_event_list;
180     btif_rc_player_app_settings_t   rc_app_settings;
181     alarm_t                     *rc_play_status_timer;
182     BOOLEAN                     rc_features_processed;
183     UINT64                      rc_playing_uid;
184     BOOLEAN                     rc_procedure_complete;
185 } btif_rc_cb_t;
186
187 typedef struct {
188     BOOLEAN in_use;
189     UINT8 lbl;
190     UINT8 handle;
191     btif_rc_timer_context_t txn_timer_context;
192     alarm_t *txn_timer;
193 } rc_transaction_t;
194
195 typedef struct
196 {
197     pthread_mutex_t lbllock;
198     rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
199 } rc_device_t;
200
201 rc_device_t device;
202
203 #define MAX_UINPUT_PATHS 3
204 static const char* uinput_dev_path[] =
205                        {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
206 static int uinput_fd = -1;
207
208 static int  send_event (int fd, uint16_t type, uint16_t code, int32_t value);
209 static void send_key (int fd, uint16_t key, int pressed);
210 static int  uinput_driver_check();
211 static int  uinput_create(char *name);
212 static int  init_uinput (void);
213 static void close_uinput (void);
214 static void sleep_ms(period_ms_t timeout_ms);
215
216 static const struct {
217     const char *name;
218     uint8_t avrcp;
219     uint16_t mapped_id;
220     uint8_t release_quirk;
221 } key_map[] = {
222     { "PLAY",         AVRC_ID_PLAY,     KEY_PLAYCD,       1 },
223     { "STOP",         AVRC_ID_STOP,     KEY_STOPCD,       0 },
224     { "PAUSE",        AVRC_ID_PAUSE,    KEY_PAUSECD,      1 },
225     { "FORWARD",      AVRC_ID_FORWARD,  KEY_NEXTSONG,     0 },
226     { "BACKWARD",     AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
227     { "REWIND",       AVRC_ID_REWIND,   KEY_REWIND,       0 },
228     { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
229     { NULL,           0,                0,                0 }
230 };
231
232 static void send_reject_response (UINT8 rc_handle, UINT8 label,
233     UINT8 pdu, UINT8 status);
234 static UINT8 opcode_from_pdu(UINT8 pdu);
235 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
236     tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
237 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
238 static void register_volumechange(UINT8 label);
239 #endif
240 static void lbl_init();
241 static void lbl_destroy();
242 static void init_all_transactions();
243 static bt_status_t  get_transaction(rc_transaction_t **ptransaction);
244 static void release_transaction(UINT8 label);
245 static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
246 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
247 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
248 #endif
249 #if (AVRC_CTLR_INCLUDED == TRUE)
250 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg);
251 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
252 static void btif_rc_ctrl_upstreams_rsp_cmd(
253     UINT8 event, tAVRC_COMMAND *pavrc_cmd, UINT8 label);
254 static void rc_ctrl_procedure_complete();
255 static void rc_stop_play_status_timer();
256 static void register_for_event_notification (btif_rc_supported_event_t *p_event);
257 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp);
258 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp);
259 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp);
260 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp);
261 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
262 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
263 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp);
264 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp);
265 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp);
266 static bt_status_t get_play_status_cmd(void);
267 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs);
268 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals);
269 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value);
270 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids);
271 static bt_status_t getcapabilities_cmd (uint8_t cap_id);
272 static bt_status_t list_player_app_setting_attrib_cmd(void);
273 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id);
274 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids);
275 #endif
276 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
277 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
278 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
279 #endif
280 static void rc_start_play_status_timer(void);
281 static bool absolute_volume_disabled(void);
282
283 /*****************************************************************************
284 **  Static variables
285 ******************************************************************************/
286 static btif_rc_cb_t btif_rc_cb;
287 static btrc_callbacks_t *bt_rc_callbacks = NULL;
288 static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
289
290 /*****************************************************************************
291 **  Static functions
292 ******************************************************************************/
293
294 /*****************************************************************************
295 **  Externs
296 ******************************************************************************/
297 extern BOOLEAN btif_hf_call_terminated_recently();
298 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
299
300 extern fixed_queue_t *btu_general_alarm_queue;
301
302 /*****************************************************************************
303 **  Functions
304 ******************************************************************************/
305
306 /*****************************************************************************
307 **   Local uinput helper functions
308 ******************************************************************************/
309 int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
310 {
311     struct uinput_event event;
312     BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__,
313         type, code, value);
314     memset(&event, 0, sizeof(event));
315     event.type  = type;
316     event.code  = code;
317     event.value = value;
318
319     return write(fd, &event, sizeof(event));
320 }
321
322 void send_key (int fd, uint16_t key, int pressed)
323 {
324     BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__,
325         fd, key, pressed);
326
327     if (fd < 0)
328     {
329         return;
330     }
331
332     BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
333     send_event(fd, EV_KEY, key, pressed);
334     send_event(fd, EV_SYN, SYN_REPORT, 0);
335 }
336
337 /************** uinput related functions **************/
338 int uinput_driver_check()
339 {
340     uint32_t i;
341     for (i=0; i < MAX_UINPUT_PATHS; i++)
342     {
343         if (access(uinput_dev_path[i], O_RDWR) == 0) {
344            return 0;
345         }
346     }
347     BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__);
348     return -1;
349 }
350
351 int uinput_create(char *name)
352 {
353     struct uinput_dev dev;
354     int fd, x = 0;
355
356     for(x=0; x < MAX_UINPUT_PATHS; x++)
357     {
358         fd = open(uinput_dev_path[x], O_RDWR);
359         if (fd < 0)
360             continue;
361         break;
362     }
363     if (x == MAX_UINPUT_PATHS) {
364         BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__);
365         return -1;
366     }
367     memset(&dev, 0, sizeof(dev));
368     if (name)
369         strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1);
370
371     dev.id.bustype = BUS_BLUETOOTH;
372     dev.id.vendor  = 0x0000;
373     dev.id.product = 0x0000;
374     dev.id.version = 0x0000;
375
376     if (write(fd, &dev, sizeof(dev)) < 0) {
377         BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
378         close(fd);
379         return -1;
380     }
381
382     ioctl(fd, UI_SET_EVBIT, EV_KEY);
383     ioctl(fd, UI_SET_EVBIT, EV_REL);
384     ioctl(fd, UI_SET_EVBIT, EV_SYN);
385
386     for (x = 0; key_map[x].name != NULL; x++)
387         ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
388
389     if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
390         BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
391         close(fd);
392         return -1;
393     }
394     return fd;
395 }
396
397 int init_uinput (void)
398 {
399     char *name = "AVRCP";
400
401     BTIF_TRACE_DEBUG("%s", __FUNCTION__);
402     uinput_fd = uinput_create(name);
403     if (uinput_fd < 0) {
404         BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)",
405                           __FUNCTION__, name, uinput_fd);
406     } else {
407         BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)",
408                           __FUNCTION__, name, uinput_fd);
409     }
410     return uinput_fd;
411 }
412
413 void close_uinput (void)
414 {
415     BTIF_TRACE_DEBUG("%s", __FUNCTION__);
416     if (uinput_fd > 0) {
417         ioctl(uinput_fd, UI_DEV_DESTROY);
418
419         close(uinput_fd);
420         uinput_fd = -1;
421     }
422 }
423
424 #if (AVRC_CTLR_INCLUDED == TRUE)
425 void rc_cleanup_sent_cmd (void *p_data)
426 {
427     BTIF_TRACE_DEBUG("%s", __FUNCTION__);
428
429 }
430
431 void handle_rc_ctrl_features(BD_ADDR bd_addr)
432 {
433     if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
434        ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
435         (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
436     {
437         bt_bdaddr_t rc_addr;
438         int rc_features = 0;
439         bdcpy(rc_addr.address,bd_addr);
440
441         if ((btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)&&
442              (btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT))
443         {
444             rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
445         }
446         if ((btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)&&
447             (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR)&&
448             (btif_rc_cb.rc_features_processed != TRUE))
449         {
450             rc_features |= BTRC_FEAT_METADATA;
451             /* Mark rc features processed to avoid repeating
452              * the AVRCP procedure every time on receiving this
453              * update.
454              */
455             btif_rc_cb.rc_features_processed = TRUE;
456             getcapabilities_cmd (AVRC_CAP_COMPANY_ID);
457         }
458         BTIF_TRACE_DEBUG("%s Update rc features to CTRL %d", __FUNCTION__, rc_features);
459         HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features);
460     }
461 }
462 #endif
463
464 void handle_rc_features(BD_ADDR bd_addr)
465 {
466     if (bt_rc_callbacks != NULL)
467     {
468     btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
469     bt_bdaddr_t rc_addr;
470
471     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
472     bt_bdaddr_t avdtp_addr  = btif_av_get_addr();
473
474     bdstr_t addr1, addr2;
475     BTIF_TRACE_DEBUG("%s: AVDTP Address: %s AVCTP address: %s", __func__,
476                      bdaddr_to_string(&avdtp_addr, addr1, sizeof(addr1)),
477                      bdaddr_to_string(&rc_addr, addr2, sizeof(addr2)));
478
479     if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr)
480         || absolute_volume_disabled()
481         || bdcmp(avdtp_addr.address, rc_addr.address))
482         btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
483
484     if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
485     {
486         rc_features |= BTRC_FEAT_BROWSE;
487     }
488
489 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
490     if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
491          (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
492     {
493         rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
494     }
495 #endif
496
497     if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
498     {
499         rc_features |= BTRC_FEAT_METADATA;
500     }
501
502     BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
503     HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
504
505 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
506      BTIF_TRACE_DEBUG("%s Checking for feature flags in btif_rc_handler with label %d",
507                         __FUNCTION__, btif_rc_cb.rc_vol_label);
508      // Register for volume change on connect
509       if (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
510          btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
511       {
512          rc_transaction_t *p_transaction=NULL;
513          bt_status_t status = BT_STATUS_NOT_READY;
514          if (MAX_LABEL==btif_rc_cb.rc_vol_label)
515          {
516             status=get_transaction(&p_transaction);
517          }
518          else
519          {
520             p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
521             if (NULL!=p_transaction)
522             {
523                BTIF_TRACE_DEBUG("%s register_volumechange already in progress for label %d",
524                                   __FUNCTION__, btif_rc_cb.rc_vol_label);
525                return;
526             }
527             else
528               status=get_transaction(&p_transaction);
529          }
530
531          if (BT_STATUS_SUCCESS == status && NULL!=p_transaction)
532          {
533             btif_rc_cb.rc_vol_label=p_transaction->lbl;
534             register_volumechange(btif_rc_cb.rc_vol_label);
535          }
536        }
537 #endif
538     }
539 }
540
541 /***************************************************************************
542  *  Function       handle_rc_connect
543  *
544  *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
545  *
546  *  - Description: RC connection event handler
547  *
548  ***************************************************************************/
549 void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
550 {
551     BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
552     bt_status_t result = BT_STATUS_SUCCESS;
553 #if (AVRC_CTLR_INCLUDED == TRUE)
554     bt_bdaddr_t rc_addr;
555 #endif
556
557     if (p_rc_open->status == BTA_AV_SUCCESS)
558     {
559         //check if already some RC is connected
560         if (btif_rc_cb.rc_connected)
561         {
562             BTIF_TRACE_ERROR("%s Got RC OPEN in connected state, Connected RC: %d \
563                 and Current RC: %d", __FUNCTION__, btif_rc_cb.rc_handle,p_rc_open->rc_handle );
564             if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle)
565                 && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr)))
566             {
567                 BTIF_TRACE_DEBUG("%s Got RC connected for some other handle", __FUNCTION__);
568                 BTA_AvCloseRc(p_rc_open->rc_handle);
569                 return;
570             }
571         }
572         memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
573         btif_rc_cb.rc_features = p_rc_open->peer_features;
574         btif_rc_cb.rc_vol_label=MAX_LABEL;
575         btif_rc_cb.rc_volume=MAX_VOLUME;
576
577         btif_rc_cb.rc_connected = TRUE;
578         btif_rc_cb.rc_handle = p_rc_open->rc_handle;
579
580         /* on locally initiated connection we will get remote features as part of connect */
581         if (btif_rc_cb.rc_features != 0)
582             handle_rc_features(btif_rc_cb.rc_addr);
583         if (bt_rc_callbacks)
584         {
585             result = uinput_driver_check();
586             if (result == BT_STATUS_SUCCESS)
587             {
588                 init_uinput();
589             }
590         }
591         else
592         {
593             BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not initializing UInput",
594                                __FUNCTION__);
595         }
596         BTIF_TRACE_DEBUG("%s handle_rc_connect features %d ",__FUNCTION__, btif_rc_cb.rc_features);
597 #if (AVRC_CTLR_INCLUDED == TRUE)
598         btif_rc_cb.rc_playing_uid = RC_INVALID_TRACK_ID;
599         bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
600         if (bt_rc_ctrl_callbacks != NULL)
601         {
602             HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
603         }
604         /* report connection state if remote device is AVRCP target */
605         if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
606            ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
607             (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
608         {
609             handle_rc_ctrl_features(btif_rc_cb.rc_addr);
610         }
611 #endif
612     }
613     else
614     {
615         BTIF_TRACE_ERROR("%s Connect failed with error code: %d",
616             __FUNCTION__, p_rc_open->status);
617         btif_rc_cb.rc_connected = FALSE;
618     }
619 }
620
621 /***************************************************************************
622  *  Function       handle_rc_disconnect
623  *
624  *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
625  *
626  *  - Description: RC disconnection event handler
627  *
628  ***************************************************************************/
629 void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
630 {
631 #if (AVRC_CTLR_INCLUDED == TRUE)
632     bt_bdaddr_t rc_addr;
633     tBTA_AV_FEAT features;
634 #endif
635     BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
636     if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle)
637         && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr)))
638     {
639         BTIF_TRACE_ERROR("Got disconnect of unknown device");
640         return;
641     }
642 #if (AVRC_CTLR_INCLUDED == TRUE)
643     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
644     features = btif_rc_cb.rc_features;
645         /* Clean up AVRCP procedure flags */
646     memset(&btif_rc_cb.rc_app_settings, 0,
647         sizeof(btif_rc_player_app_settings_t));
648     btif_rc_cb.rc_features_processed = FALSE;
649     btif_rc_cb.rc_procedure_complete = FALSE;
650     rc_stop_play_status_timer();
651     /* Check and clear the notification event list */
652     if (btif_rc_cb.rc_supported_event_list != NULL)
653     {
654         list_clear(btif_rc_cb.rc_supported_event_list);
655         btif_rc_cb.rc_supported_event_list = NULL;
656     }
657 #endif
658     btif_rc_cb.rc_handle = 0;
659     btif_rc_cb.rc_connected = FALSE;
660     memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
661     memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif));
662
663     btif_rc_cb.rc_features = 0;
664     btif_rc_cb.rc_vol_label=MAX_LABEL;
665     btif_rc_cb.rc_volume=MAX_VOLUME;
666     init_all_transactions();
667     if (bt_rc_callbacks != NULL)
668     {
669         close_uinput();
670     }
671     else
672     {
673         BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not closing UInput", __FUNCTION__);
674     }
675
676     memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
677 #if (AVRC_CTLR_INCLUDED == TRUE)
678     /* report connection state if device is AVRCP target */
679     if (bt_rc_ctrl_callbacks != NULL)
680    {
681         HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
682    }
683 #endif
684 }
685
686 /***************************************************************************
687  *  Function       handle_rc_passthrough_cmd
688  *
689  *  - Argument:    tBTA_AV_RC rc_id   remote control command ID
690  *                 tBTA_AV_STATE key_state status of key press
691  *
692  *  - Description: Remote control command handler
693  *
694  ***************************************************************************/
695 void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
696 {
697     const char *status;
698     int pressed, i;
699
700     BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
701
702     /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
703     if (p_remote_cmd)
704     {
705         /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
706         if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
707         {
708             if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
709             {
710                 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
711                 btif_rc_cb.rc_pending_play = TRUE;
712             }
713             return;
714         }
715
716         if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
717         {
718             APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
719             btif_rc_cb.rc_pending_play = FALSE;
720             return;
721         }
722         if ((p_remote_cmd->rc_id == BTA_AV_RC_VOL_UP)||(p_remote_cmd->rc_id == BTA_AV_RC_VOL_DOWN))
723             return; // this command is not to be sent to UINPUT, only needed for PTS
724     }
725
726     if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready()))
727     {
728         APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__);
729         return;
730     }
731
732     if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
733         status = "released";
734         pressed = 0;
735     } else {
736         status = "pressed";
737         pressed = 1;
738     }
739
740     if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
741         HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
742         return;
743     }
744
745     for (i = 0; key_map[i].name != NULL; i++) {
746         if (p_remote_cmd->rc_id == key_map[i].avrcp) {
747             BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status);
748
749            /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
750             * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
751             * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
752             * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
753             * The fix is to generate a release right after the press and drown the 'actual'
754             * release.
755             */
756             if ((key_map[i].release_quirk == 1) && (pressed == 0))
757             {
758                 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now",
759                                   __FUNCTION__, key_map[i].name);
760                 return;
761             }
762             send_key(uinput_fd, key_map[i].mapped_id, pressed);
763             if ((key_map[i].release_quirk == 1) && (pressed == 1))
764             {
765                 sleep_ms(30);
766                 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now",
767                                   __FUNCTION__, key_map[i].name);
768                 send_key(uinput_fd, key_map[i].mapped_id, 0);
769             }
770             break;
771         }
772     }
773
774     if (key_map[i].name == NULL)
775         BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
776                         p_remote_cmd->rc_id, status);
777 }
778
779 /***************************************************************************
780  *  Function       handle_rc_passthrough_rsp
781  *
782  *  - Argument:    tBTA_AV_REMOTE_RSP passthrough command response
783  *
784  *  - Description: Remote control passthrough response handler
785  *
786  ***************************************************************************/
787 void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
788 {
789 #if (AVRC_CTLR_INCLUDED == TRUE)
790     const char *status;
791     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
792     {
793         int key_state;
794         if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
795         {
796             status = "released";
797             key_state = 1;
798         }
799         else
800         {
801             status = "pressed";
802             key_state = 0;
803         }
804
805         BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
806
807         release_transaction(p_remote_rsp->label);
808         if (bt_rc_ctrl_callbacks != NULL) {
809             HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
810         }
811     }
812     else
813     {
814         BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
815     }
816 #else
817     BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
818 #endif
819 }
820
821 /***************************************************************************
822  *  Function       handle_rc_vendorunique_rsp
823  *
824  *  - Argument:    tBTA_AV_REMOTE_RSP  command response
825  *
826  *  - Description: Remote control vendor unique response handler
827  *
828  ***************************************************************************/
829 void handle_rc_vendorunique_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
830 {
831 #if (AVRC_CTLR_INCLUDED == TRUE)
832     const char *status;
833     UINT8 vendor_id = 0;
834     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
835     {
836         int key_state;
837         if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
838         {
839             status = "released";
840             key_state = 1;
841         }
842         else
843         {
844             status = "pressed";
845             key_state = 0;
846         }
847
848         if (p_remote_rsp->len > 0)
849         {
850             if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN)
851                 vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN -1];
852             osi_free_and_reset((void **)&p_remote_rsp->p_data);
853         }
854         BTIF_TRACE_DEBUG("%s: vendor_id=%d status=%s", __FUNCTION__, vendor_id, status);
855
856         release_transaction(p_remote_rsp->label);
857         HAL_CBACK(bt_rc_ctrl_callbacks, groupnavigation_rsp_cb, vendor_id, key_state);
858     }
859     else
860     {
861         BTIF_TRACE_ERROR("%s Remote does not support AVRCP TG role", __FUNCTION__);
862     }
863 #else
864     BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
865 #endif
866 }
867
868 void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
869 {
870     tAVRC_RESPONSE avrc_rsp = {0};
871     avrc_rsp.rsp.pdu = pavrc_command->pdu;
872     avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
873     avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
874
875     avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
876     avrc_rsp.reg_notif.param.uid_counter = 0;
877
878     send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
879     send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
880
881 }
882
883 /***************************************************************************
884  *  Function       handle_rc_metamsg_cmd
885  *
886  *  - Argument:    tBTA_AV_VENDOR Structure containing the received
887  *                          metamsg command
888  *
889  *  - Description: Remote control metamsg command handler (AVRCP 1.3)
890  *
891  ***************************************************************************/
892 void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
893 {
894     /* Parse the metamsg command and pass it on to BTL-IFS */
895     UINT8             scratch_buf[512] = {0};
896     tAVRC_COMMAND    avrc_command = {0};
897     tAVRC_STS status;
898
899     BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
900
901     if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
902     {
903         BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
904         return;
905     }
906     if (pmeta_msg->len < 3)
907     {
908         BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
909             pmeta_msg->len);
910         return;
911     }
912
913     if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
914     {
915 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
916 {
917      rc_transaction_t *transaction=NULL;
918      transaction=get_transaction_by_lbl(pmeta_msg->label);
919      if (NULL!=transaction)
920      {
921         handle_rc_metamsg_rsp(pmeta_msg);
922      }
923      else
924      {
925          BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
926              __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
927      }
928      return;
929 }
930 #else
931 {
932         BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
933             __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
934         return;
935 }
936 #endif
937       }
938
939     status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
940     BTIF_TRACE_DEBUG("%s Received vendor command.code,PDU and label: %d, %d,%d",
941                      __FUNCTION__, pmeta_msg->code, avrc_command.cmd.pdu, pmeta_msg->label);
942
943     if (status != AVRC_STS_NO_ERROR)
944     {
945         /* return error */
946         BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
947             __FUNCTION__, status);
948         send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
949     }
950     else
951     {
952         /* if RegisterNotification, add it to our registered queue */
953
954         if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
955         {
956             UINT8 event_id = avrc_command.reg_notif.event_id;
957             BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
958             __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
959             btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
960             btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
961
962             if (event_id == AVRC_EVT_UIDS_CHANGE)
963             {
964                 handle_uid_changed_notification(pmeta_msg, &avrc_command);
965                 return;
966             }
967
968         }
969
970         BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
971             __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
972
973         /* Since handle_rc_metamsg_cmd() itself is called from
974             *btif context, no context switching is required. Invoke
975             * btif_rc_upstreams_evt directly from here. */
976         btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
977                                pmeta_msg->label);
978     }
979 }
980
981 /***************************************************************************
982  **
983  ** Function       btif_rc_handler
984  **
985  ** Description    RC event handler
986  **
987  ***************************************************************************/
988 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
989 {
990     BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
991     switch (event)
992     {
993         case BTA_AV_RC_OPEN_EVT:
994         {
995             BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_open.peer_features);
996             handle_rc_connect( &(p_data->rc_open) );
997         }break;
998
999         case BTA_AV_RC_CLOSE_EVT:
1000         {
1001             handle_rc_disconnect( &(p_data->rc_close) );
1002         }break;
1003
1004         case BTA_AV_REMOTE_CMD_EVT:
1005         {
1006             if (bt_rc_callbacks != NULL)
1007             {
1008               BTIF_TRACE_DEBUG("%s rc_id:0x%x key_state:%d",
1009                                __FUNCTION__, p_data->remote_cmd.rc_id,
1010                                p_data->remote_cmd.key_state);
1011                 /** In race conditions just after 2nd AVRCP is connected
1012                  *  remote might send pass through commands, so check for
1013                  *  Rc handle before processing pass through commands
1014                  **/
1015                 if (btif_rc_cb.rc_handle == p_data->remote_cmd.rc_handle)
1016                 {
1017                     handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
1018                 }
1019                 else
1020                 {
1021                     BTIF_TRACE_DEBUG("%s Pass-through command for Invalid rc handle", __FUNCTION__);
1022                 }
1023             }
1024             else
1025             {
1026                 BTIF_TRACE_ERROR("AVRCP TG role not up, drop passthrough commands");
1027             }
1028         }
1029         break;
1030
1031 #if (AVRC_CTLR_INCLUDED == TRUE)
1032         case BTA_AV_REMOTE_RSP_EVT:
1033         {
1034             BTIF_TRACE_DEBUG("%s RSP: rc_id:0x%x key_state:%d",
1035                              __FUNCTION__, p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state);
1036             if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR)
1037             {
1038                 handle_rc_vendorunique_rsp(&p_data->remote_rsp);
1039             }
1040             else
1041             {
1042                 handle_rc_passthrough_rsp(&p_data->remote_rsp);
1043             }
1044         }
1045         break;
1046
1047 #endif
1048         case BTA_AV_RC_FEAT_EVT:
1049         {
1050             BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_feat.peer_features);
1051             btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
1052             handle_rc_features(p_data->rc_feat.peer_addr);
1053 #if (AVRC_CTLR_INCLUDED == TRUE)
1054             if ((btif_rc_cb.rc_connected) && (bt_rc_ctrl_callbacks != NULL))
1055             {
1056                 handle_rc_ctrl_features(btif_rc_cb.rc_addr);
1057             }
1058 #endif
1059         }
1060         break;
1061
1062         case BTA_AV_META_MSG_EVT:
1063         {
1064             if (bt_rc_callbacks != NULL)
1065             {
1066                 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT  code:%d label:%d",
1067                                  __FUNCTION__,
1068                                  p_data->meta_msg.code,
1069                                  p_data->meta_msg.label);
1070                 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1071                                  __FUNCTION__,
1072                                  p_data->meta_msg.company_id,
1073                                  p_data->meta_msg.len,
1074                                  p_data->meta_msg.rc_handle);
1075                 /* handle the metamsg command */
1076                 handle_rc_metamsg_cmd(&(p_data->meta_msg));
1077                 /* Free the Memory allocated for tAVRC_MSG */
1078             }
1079 #if (AVRC_CTLR_INCLUDED == TRUE)
1080             else if ((bt_rc_callbacks == NULL)&&(bt_rc_ctrl_callbacks != NULL))
1081             {
1082                 /* This is case of Sink + CT + TG(for abs vol)) */
1083                 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT  code:%d label:%d",
1084                                  __FUNCTION__,
1085                                  p_data->meta_msg.code,
1086                                  p_data->meta_msg.label);
1087                 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1088                                  __FUNCTION__,
1089                                  p_data->meta_msg.company_id,
1090                                  p_data->meta_msg.len,
1091                                  p_data->meta_msg.rc_handle);
1092                 if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL)&&
1093                     (p_data->meta_msg.code <= AVRC_RSP_INTERIM))
1094                 {
1095                     /* Its a response */
1096                     handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
1097                 }
1098                 else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ)
1099                 {
1100                     /* Its a command  */
1101                     handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
1102                 }
1103
1104             }
1105 #endif
1106             else
1107             {
1108                 BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands");
1109             }
1110         }
1111         break;
1112
1113         default:
1114             BTIF_TRACE_DEBUG("%s Unhandled RC event : 0x%x", __FUNCTION__, event);
1115     }
1116 }
1117
1118 /***************************************************************************
1119  **
1120  ** Function       btif_rc_get_connected_peer
1121  **
1122  ** Description    Fetches the connected headset's BD_ADDR if any
1123  **
1124  ***************************************************************************/
1125 BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
1126 {
1127     if (btif_rc_cb.rc_connected == TRUE) {
1128         bdcpy(peer_addr, btif_rc_cb.rc_addr);
1129         return TRUE;
1130     }
1131     return FALSE;
1132 }
1133
1134 /***************************************************************************
1135  **
1136  ** Function       btif_rc_get_connected_peer_handle
1137  **
1138  ** Description    Fetches the connected headset's handle if any
1139  **
1140  ***************************************************************************/
1141 UINT8 btif_rc_get_connected_peer_handle(void)
1142 {
1143     return btif_rc_cb.rc_handle;
1144 }
1145
1146 /***************************************************************************
1147  **
1148  ** Function       btif_rc_check_handle_pending_play
1149  **
1150  ** Description    Clears the queued PLAY command. if bSend is TRUE, forwards to app
1151  **
1152  ***************************************************************************/
1153
1154 /* clear the queued PLAY command. if bSend is TRUE, forward to app */
1155 void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
1156 {
1157     UNUSED(peer_addr);
1158
1159     BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
1160     if (btif_rc_cb.rc_pending_play)
1161     {
1162         if (bSendToApp)
1163         {
1164             tBTA_AV_REMOTE_CMD remote_cmd;
1165             APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
1166
1167             memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
1168             remote_cmd.rc_handle  = btif_rc_cb.rc_handle;
1169             remote_cmd.rc_id      = AVRC_ID_PLAY;
1170             remote_cmd.hdr.ctype  = AVRC_CMD_CTRL;
1171             remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
1172
1173             /* delay sending to app, else there is a timing issue in the framework,
1174              ** which causes the audio to be on th device's speaker. Delay between
1175              ** OPEN & RC_PLAYs
1176             */
1177             sleep_ms(200);
1178             /* send to app - both PRESSED & RELEASED */
1179             remote_cmd.key_state  = AVRC_STATE_PRESS;
1180             handle_rc_passthrough_cmd( &remote_cmd );
1181
1182             sleep_ms(100);
1183
1184             remote_cmd.key_state  = AVRC_STATE_RELEASE;
1185             handle_rc_passthrough_cmd( &remote_cmd );
1186         }
1187         btif_rc_cb.rc_pending_play = FALSE;
1188     }
1189 }
1190
1191 /* Generic reject response */
1192 static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
1193 {
1194     UINT8 ctype = AVRC_RSP_REJ;
1195     tAVRC_RESPONSE avrc_rsp;
1196     BT_HDR *p_msg = NULL;
1197     memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1198
1199     avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
1200     avrc_rsp.rsp.pdu    = pdu;
1201     avrc_rsp.rsp.status = status;
1202
1203     if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
1204     {
1205         BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
1206             __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
1207         BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1208     }
1209 }
1210
1211 /***************************************************************************
1212  *  Function       send_metamsg_rsp
1213  *
1214  *  - Argument:
1215  *                  rc_handle     RC handle corresponding to the connected RC
1216  *                  label            Label of the RC response
1217  *                  code            Response type
1218  *                  pmetamsg_resp    Vendor response
1219  *
1220  *  - Description: Remote control metamsg response handler (AVRCP 1.3)
1221  *
1222  ***************************************************************************/
1223 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
1224     tAVRC_RESPONSE *pmetamsg_resp)
1225 {
1226     UINT8 ctype;
1227
1228     if (!pmetamsg_resp)
1229     {
1230         BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
1231         return;
1232     }
1233
1234     BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
1235         rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
1236
1237     if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
1238     {
1239         ctype = AVRC_RSP_REJ;
1240     }
1241     else
1242     {
1243         if ( code < AVRC_RSP_NOT_IMPL)
1244         {
1245             if (code == AVRC_CMD_NOTIF)
1246             {
1247                ctype = AVRC_RSP_INTERIM;
1248             }
1249             else if (code == AVRC_CMD_STATUS)
1250             {
1251                ctype = AVRC_RSP_IMPL_STBL;
1252             }
1253             else
1254             {
1255                ctype = AVRC_RSP_ACCEPT;
1256             }
1257         }
1258         else
1259         {
1260             ctype = code;
1261         }
1262     }
1263     /* if response is for register_notification, make sure the rc has
1264     actually registered for this */
1265     if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
1266     {
1267         BOOLEAN bSent = FALSE;
1268         UINT8   event_id = pmetamsg_resp->reg_notif.event_id;
1269         BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
1270
1271         /* de-register this notification for a CHANGED response */
1272         btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
1273         BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
1274              btif_rc_cb.rc_handle, event_id, bNotify);
1275         if (bNotify)
1276         {
1277             BT_HDR *p_msg = NULL;
1278             tAVRC_STS status;
1279
1280             if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
1281                 pmetamsg_resp, &p_msg)) )
1282             {
1283                 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
1284                      __FUNCTION__, btif_rc_cb.rc_handle, event_id);
1285                 bSent = TRUE;
1286                 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1287                     ctype, p_msg);
1288             }
1289             else
1290             {
1291                 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
1292                     __FUNCTION__, status);
1293             }
1294
1295         }
1296
1297         if (!bSent)
1298         {
1299             BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
1300                 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1301         }
1302     }
1303     else
1304     {
1305         /* All other commands go here */
1306
1307         BT_HDR *p_msg = NULL;
1308         tAVRC_STS status;
1309
1310         status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
1311
1312         if (status == AVRC_STS_NO_ERROR)
1313         {
1314             BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1315         }
1316         else
1317         {
1318             BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1319                 __FUNCTION__, status);
1320         }
1321     }
1322 }
1323
1324 static UINT8 opcode_from_pdu(UINT8 pdu)
1325 {
1326     UINT8 opcode = 0;
1327
1328     switch (pdu)
1329     {
1330     case AVRC_PDU_NEXT_GROUP:
1331     case AVRC_PDU_PREV_GROUP: /* pass thru */
1332         opcode  = AVRC_OP_PASS_THRU;
1333         break;
1334
1335     default: /* vendor */
1336         opcode  = AVRC_OP_VENDOR;
1337         break;
1338     }
1339
1340     return opcode;
1341 }
1342
1343 /*******************************************************************************
1344 **
1345 ** Function         btif_rc_upstreams_evt
1346 **
1347 ** Description      Executes AVRC UPSTREAMS events in btif context.
1348 **
1349 ** Returns          void
1350 **
1351 *******************************************************************************/
1352 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1353 {
1354     BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1355         dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1356
1357     switch (event)
1358     {
1359         case AVRC_PDU_GET_PLAY_STATUS:
1360         {
1361             FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1362             HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1363         }
1364         break;
1365         case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1366         case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1367         case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1368         case AVRC_PDU_SET_PLAYER_APP_VALUE:
1369         case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1370         case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1371         {
1372             /* TODO: Add support for Application Settings */
1373             send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
1374         }
1375         break;
1376         case AVRC_PDU_GET_ELEMENT_ATTR:
1377         {
1378             btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1379             UINT8 num_attr;
1380              memset(&element_attrs, 0, sizeof(element_attrs));
1381             if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1382             {
1383                 /* CT requests for all attributes */
1384                 int attr_cnt;
1385                 num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1386                 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
1387                 {
1388                     element_attrs[attr_cnt] = attr_cnt + 1;
1389                 }
1390             }
1391             else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1392             {
1393                 /* 0xff indicates, no attributes requested - reject */
1394                 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1395                     AVRC_STS_BAD_PARAM);
1396                 return;
1397             }
1398             else
1399             {
1400                 int attr_cnt, filled_attr_count;
1401
1402                 num_attr = 0;
1403                 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid,
1404                  * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID.
1405                  * Fill only valid entries.
1406                  */
1407                 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) &&
1408                     (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++)
1409                 {
1410                     if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) &&
1411                         (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID))
1412                     {
1413                         /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases
1414                          */
1415                         for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++)
1416                         {
1417                             if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt])
1418                                 break;
1419                         }
1420                         if (filled_attr_count == num_attr)
1421                         {
1422                             element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt];
1423                             num_attr++;
1424                         }
1425                     }
1426                 }
1427             }
1428             FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1429             HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1430         }
1431         break;
1432         case AVRC_PDU_REGISTER_NOTIFICATION:
1433         {
1434             if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1435                 pavrc_cmd->reg_notif.param == 0)
1436             {
1437                 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
1438                     __FUNCTION__);
1439                 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1440                 /* de-register this notification for a rejected response */
1441                 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1442                 return;
1443             }
1444             HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1445                 pavrc_cmd->reg_notif.param);
1446         }
1447         break;
1448         case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1449         {
1450             tAVRC_RESPONSE avrc_rsp;
1451             BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
1452             if (btif_rc_cb.rc_connected == TRUE)
1453             {
1454                 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1455                 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1456                 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1457                 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1458                 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1459             }
1460         }
1461         break;
1462         default:
1463         {
1464         send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1465             (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1466         return;
1467         }
1468         break;
1469     }
1470 }
1471
1472 #if (AVRC_CTLR_INCLUDED == TRUE)
1473 /*******************************************************************************
1474 **
1475 ** Function         btif_rc_ctrl_upstreams_rsp_cmd
1476 **
1477 ** Description      Executes AVRC UPSTREAMS response events in btif context.
1478 **
1479 ** Returns          void
1480 **
1481 *******************************************************************************/
1482 static void btif_rc_ctrl_upstreams_rsp_cmd(UINT8 event, tAVRC_COMMAND *pavrc_cmd,
1483         UINT8 label)
1484 {
1485     BTIF_TRACE_DEBUG("%s pdu: %s handle: 0x%x", __FUNCTION__,
1486         dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle);
1487     bt_bdaddr_t rc_addr;
1488     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
1489 #if (AVRC_CTLR_INCLUDED == TRUE)
1490     switch (event)
1491     {
1492     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1493          HAL_CBACK(bt_rc_ctrl_callbacks,setabsvol_cmd_cb, &rc_addr,
1494                  pavrc_cmd->volume.volume, label);
1495          break;
1496     case AVRC_PDU_REGISTER_NOTIFICATION:
1497          if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE)
1498          {
1499              HAL_CBACK(bt_rc_ctrl_callbacks, registernotification_absvol_cb,
1500                     &rc_addr, label);
1501          }
1502          break;
1503     }
1504 #endif
1505 }
1506 #endif
1507
1508 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1509 /*******************************************************************************
1510 **
1511 ** Function         btif_rc_upstreams_rsp_evt
1512 **
1513 ** Description      Executes AVRC UPSTREAMS response events in btif context.
1514 **
1515 ** Returns          void
1516 **
1517 *******************************************************************************/
1518 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1519 {
1520     BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1521         dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1522
1523     switch (event)
1524     {
1525         case AVRC_PDU_REGISTER_NOTIFICATION:
1526         {
1527              if (AVRC_RSP_CHANGED==ctype)
1528                  btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1529              HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1530         }
1531         break;
1532
1533         case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1534         {
1535             BTIF_TRACE_DEBUG("%s Set absolute volume change event received: volume %d,ctype %d",
1536                              __FUNCTION__, pavrc_resp->volume.volume,ctype);
1537             if (AVRC_RSP_ACCEPT==ctype)
1538                 btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1539             HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1540         }
1541         break;
1542
1543         default:
1544             return;
1545     }
1546 }
1547 #endif
1548
1549 /************************************************************************************
1550 **  AVRCP API Functions
1551 ************************************************************************************/
1552
1553 /*******************************************************************************
1554 **
1555 ** Function         init
1556 **
1557 ** Description      Initializes the AVRC interface
1558 **
1559 ** Returns          bt_status_t
1560 **
1561 *******************************************************************************/
1562 static bt_status_t init(btrc_callbacks_t* callbacks )
1563 {
1564     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1565     bt_status_t result = BT_STATUS_SUCCESS;
1566
1567     if (bt_rc_callbacks)
1568         return BT_STATUS_DONE;
1569
1570     bt_rc_callbacks = callbacks;
1571     memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1572     btif_rc_cb.rc_vol_label=MAX_LABEL;
1573     btif_rc_cb.rc_volume=MAX_VOLUME;
1574     lbl_init();
1575
1576     return result;
1577 }
1578
1579 /*******************************************************************************
1580 **
1581 ** Function         init_ctrl
1582 **
1583 ** Description      Initializes the AVRC interface
1584 **
1585 ** Returns          bt_status_t
1586 **
1587 *******************************************************************************/
1588 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1589 {
1590     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1591     bt_status_t result = BT_STATUS_SUCCESS;
1592
1593     if (bt_rc_ctrl_callbacks)
1594         return BT_STATUS_DONE;
1595
1596     bt_rc_ctrl_callbacks = callbacks;
1597     memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1598     btif_rc_cb.rc_vol_label=MAX_LABEL;
1599     btif_rc_cb.rc_volume=MAX_VOLUME;
1600     lbl_init();
1601
1602     return result;
1603 }
1604
1605 static void rc_ctrl_procedure_complete ()
1606 {
1607     if (btif_rc_cb.rc_procedure_complete == TRUE)
1608     {
1609         return;
1610     }
1611     btif_rc_cb.rc_procedure_complete = TRUE;
1612     UINT32 attr_list[] = {
1613             AVRC_MEDIA_ATTR_ID_TITLE,
1614             AVRC_MEDIA_ATTR_ID_ARTIST,
1615             AVRC_MEDIA_ATTR_ID_ALBUM,
1616             AVRC_MEDIA_ATTR_ID_TRACK_NUM,
1617             AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
1618             AVRC_MEDIA_ATTR_ID_GENRE,
1619             AVRC_MEDIA_ATTR_ID_PLAYING_TIME
1620             };
1621     get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
1622 }
1623
1624 /***************************************************************************
1625 **
1626 ** Function         get_play_status_rsp
1627 **
1628 ** Description      Returns the current play status.
1629 **                      This method is called in response to
1630 **                      GetPlayStatus request.
1631 **
1632 ** Returns          bt_status_t
1633 **
1634 ***************************************************************************/
1635 static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1636     uint32_t song_pos)
1637 {
1638     tAVRC_RESPONSE avrc_rsp;
1639     CHECK_RC_CONNECTED
1640     memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1641     avrc_rsp.get_play_status.song_len = song_len;
1642     avrc_rsp.get_play_status.song_pos = song_pos;
1643     avrc_rsp.get_play_status.play_status = play_status;
1644
1645     avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1646     avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1647     avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1648     /* Send the response */
1649     SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1650     return BT_STATUS_SUCCESS;
1651 }
1652
1653 /***************************************************************************
1654 **
1655 ** Function         get_element_attr_rsp
1656 **
1657 ** Description      Returns the current songs' element attributes
1658 **                      in text.
1659 **
1660 ** Returns          bt_status_t
1661 **
1662 ***************************************************************************/
1663 static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1664 {
1665     tAVRC_RESPONSE avrc_rsp;
1666     UINT32 i;
1667     tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1668     CHECK_RC_CONNECTED
1669     memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1670
1671     if (num_attr == 0)
1672     {
1673         avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1674     }
1675     else
1676     {
1677         for (i=0; i<num_attr; i++) {
1678             element_attrs[i].attr_id = p_attrs[i].attr_id;
1679             element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1680             element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1681             element_attrs[i].name.p_str = p_attrs[i].text;
1682             BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
1683                              __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1684                              element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1685                              element_attrs[i].name.p_str);
1686         }
1687         avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1688     }
1689     avrc_rsp.get_elem_attrs.num_attr = num_attr;
1690     avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1691     avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1692     avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1693     /* Send the response */
1694     SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1695     return BT_STATUS_SUCCESS;
1696 }
1697
1698 /***************************************************************************
1699 **
1700 ** Function         register_notification_rsp
1701 **
1702 ** Description      Response to the register notification request.
1703 **                      in text.
1704 **
1705 ** Returns          bt_status_t
1706 **
1707 ***************************************************************************/
1708 static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1709     btrc_notification_type_t type, btrc_register_notification_t *p_param)
1710 {
1711     tAVRC_RESPONSE avrc_rsp;
1712     CHECK_RC_CONNECTED
1713     BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1714     if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
1715     {
1716         BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
1717         return BT_STATUS_NOT_READY;
1718     }
1719     memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1720     avrc_rsp.reg_notif.event_id = event_id;
1721
1722     switch(event_id)
1723     {
1724         case BTRC_EVT_PLAY_STATUS_CHANGED:
1725             avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1726             if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING)
1727                 btif_av_clear_remote_suspend_flag();
1728             break;
1729         case BTRC_EVT_TRACK_CHANGE:
1730             memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1731             break;
1732         case BTRC_EVT_PLAY_POS_CHANGED:
1733             avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1734             break;
1735         default:
1736             BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
1737             return BT_STATUS_UNHANDLED;
1738     }
1739
1740     avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1741     avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1742     avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1743
1744     /* Send the response. */
1745     send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1746         ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1747     return BT_STATUS_SUCCESS;
1748 }
1749
1750 /***************************************************************************
1751 **
1752 ** Function         set_volume
1753 **
1754 ** Description      Send current volume setting to remote side.
1755 **                  Support limited to SetAbsoluteVolume
1756 **                  This can be enhanced to support Relative Volume (AVRCP 1.0).
1757 **                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1758 **                  as opposed to absolute volume level
1759 ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1760 **
1761 ** Returns          bt_status_t
1762 **
1763 ***************************************************************************/
1764 static bt_status_t set_volume(uint8_t volume)
1765 {
1766     BTIF_TRACE_DEBUG("%s", __FUNCTION__);
1767     CHECK_RC_CONNECTED
1768     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1769     rc_transaction_t *p_transaction=NULL;
1770
1771     if (btif_rc_cb.rc_volume==volume)
1772     {
1773         status=BT_STATUS_DONE;
1774         BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
1775         return status;
1776     }
1777
1778     if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1779         (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1780     {
1781         tAVRC_COMMAND avrc_cmd = {0};
1782         BT_HDR *p_msg = NULL;
1783
1784         BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
1785         avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1786         avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1787         avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1788         avrc_cmd.volume.volume = volume;
1789
1790         if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1791         {
1792             bt_status_t tran_status=get_transaction(&p_transaction);
1793             if (BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1794             {
1795                 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
1796                                    __FUNCTION__,p_transaction->lbl);
1797                 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1798                 status =  BT_STATUS_SUCCESS;
1799             }
1800             else
1801             {
1802                 osi_free(p_msg);
1803                 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
1804                                     __FUNCTION__, tran_status);
1805                 status = BT_STATUS_FAIL;
1806             }
1807         }
1808         else
1809         {
1810             BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
1811                                 __FUNCTION__, status);
1812             status = BT_STATUS_FAIL;
1813         }
1814     }
1815     else
1816         status=BT_STATUS_NOT_READY;
1817     return status;
1818 }
1819
1820 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1821 /***************************************************************************
1822 **
1823 ** Function         register_volumechange
1824 **
1825 ** Description     Register for volume change notification from remote side.
1826 **
1827 ** Returns          void
1828 **
1829 ***************************************************************************/
1830
1831 static void register_volumechange (UINT8 lbl)
1832 {
1833     tAVRC_COMMAND avrc_cmd = {0};
1834     BT_HDR *p_msg = NULL;
1835     tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
1836     rc_transaction_t *p_transaction=NULL;
1837
1838     BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
1839
1840     avrc_cmd.cmd.opcode=0x00;
1841     avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1842     avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1843     avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1844     avrc_cmd.reg_notif.param = 0;
1845
1846     BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1847     if (AVRC_STS_NO_ERROR == BldResp && p_msg) {
1848         p_transaction = get_transaction_by_lbl(lbl);
1849         if (p_transaction != NULL) {
1850             BTA_AvMetaCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
1851                           AVRC_CMD_NOTIF, p_msg);
1852             BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called", __func__);
1853          } else {
1854             osi_free(p_msg);
1855             BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",
1856                              __func__, lbl);
1857          }
1858     } else {
1859         BTIF_TRACE_ERROR("%s failed to build command:%d", __func__, BldResp);
1860     }
1861 }
1862
1863 /***************************************************************************
1864 **
1865 ** Function         handle_rc_metamsg_rsp
1866 **
1867 ** Description      Handle RC metamessage response
1868 **
1869 ** Returns          void
1870 **
1871 ***************************************************************************/
1872 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1873 {
1874     tAVRC_RESPONSE    avrc_response = {0};
1875     UINT8             scratch_buf[512] = {0};
1876     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1877
1878     if (AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1879       || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1880       || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1881     {
1882         status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
1883         BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
1884           __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1885           status, pmeta_msg->label);
1886
1887         if (status != AVRC_STS_NO_ERROR)
1888         {
1889             if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1890                 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1891                 && btif_rc_cb.rc_vol_label==pmeta_msg->label)
1892             {
1893                 btif_rc_cb.rc_vol_label=MAX_LABEL;
1894                 release_transaction(btif_rc_cb.rc_vol_label);
1895             }
1896             else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1897             {
1898                 release_transaction(pmeta_msg->label);
1899             }
1900             return;
1901         }
1902         else if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1903             && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1904             && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1905             {
1906                 // Just discard the message, if the device sends back with an incorrect label
1907                 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
1908                 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1909                 return;
1910             }
1911     }
1912     else
1913     {
1914         BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
1915         __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1916         return;
1917     }
1918
1919     if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1920         && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1921         && AVRC_RSP_CHANGED==pmeta_msg->code)
1922      {
1923          /* re-register for volume change notification */
1924          // Do not re-register for rejected case, as it might get into endless loop
1925          register_volumechange(btif_rc_cb.rc_vol_label);
1926      }
1927      else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1928      {
1929           /* free up the label here */
1930           release_transaction(pmeta_msg->label);
1931      }
1932
1933      BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
1934              __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1935      btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1936                                 pmeta_msg->label);
1937 }
1938 #endif
1939
1940 #if (AVRC_CTLR_INCLUDED == TRUE)
1941 /***************************************************************************
1942 **
1943 ** Function         iterate_supported_event_list_for_interim_rsp
1944 **
1945 ** Description      iterator callback function to match the event and handle
1946 **                  timer cleanup
1947 ** Returns          true to continue iterating, false to stop
1948 **
1949 ***************************************************************************/
1950 bool iterate_supported_event_list_for_interim_rsp(void *data, void *cb_data)
1951 {
1952     UINT8 *p_event_id;
1953     btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1954
1955     p_event_id = (UINT8*)cb_data;
1956
1957     if (p_event->event_id == *p_event_id)
1958     {
1959         p_event->status = eINTERIM;
1960         return false;
1961     }
1962     return true;
1963 }
1964
1965 /***************************************************************************
1966 **
1967 ** Function         iterate_supported_event_list_for_timeout
1968 **
1969 ** Description      Iterator callback function for timeout handling.
1970 **                  As part of the failure handling, it releases the
1971 **                  transaction label and removes the event from list,
1972 **                  this event will not be requested again during
1973 **                  the lifetime of the connection.
1974 ** Returns          false to stop iterating, true to continue
1975 **
1976 ***************************************************************************/
1977 bool iterate_supported_event_list_for_timeout(void *data, void *cb_data)
1978 {
1979     UINT8 label;
1980     btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1981
1982     label = (*(UINT8*)cb_data) & 0xFF;
1983
1984     if (p_event->label == label)
1985     {
1986         list_remove(btif_rc_cb.rc_supported_event_list, p_event);
1987         return false;
1988     }
1989     return true;
1990 }
1991
1992 /***************************************************************************
1993 **
1994 ** Function         rc_notification_interim_timout
1995 **
1996 ** Description      Interim response timeout handler.
1997 **                  Runs the iterator to check and clear the timed out event.
1998 **                  Proceeds to register for the unregistered events.
1999 ** Returns          None
2000 **
2001 ***************************************************************************/
2002 static void rc_notification_interim_timout (UINT8 label)
2003 {
2004     list_node_t *node;
2005
2006     list_foreach(btif_rc_cb.rc_supported_event_list,
2007                      iterate_supported_event_list_for_timeout, &label);
2008     /* Timeout happened for interim response for the registered event,
2009      * check if there are any pending for registration
2010      */
2011     node = list_begin(btif_rc_cb.rc_supported_event_list);
2012     while (node != NULL)
2013     {
2014         btif_rc_supported_event_t *p_event;
2015
2016         p_event = (btif_rc_supported_event_t *)list_node(node);
2017         if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2018         {
2019             register_for_event_notification(p_event);
2020             break;
2021         }
2022         node = list_next (node);
2023     }
2024     /* Todo. Need to initiate application settings query if this
2025      * is the last event registration.
2026      */
2027 }
2028
2029 /***************************************************************************
2030 **
2031 ** Function         btif_rc_status_cmd_timeout_handler
2032 **
2033 ** Description      RC status command timeout handler (Runs in BTIF context).
2034 ** Returns          None
2035 **
2036 ***************************************************************************/
2037 static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2038                                                char *data)
2039 {
2040     btif_rc_timer_context_t *p_context;
2041     tAVRC_RESPONSE      avrc_response = {0};
2042     tBTA_AV_META_MSG    meta_msg;
2043
2044     p_context = (btif_rc_timer_context_t *)data;
2045     memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2046     meta_msg.rc_handle = btif_rc_cb.rc_handle;
2047
2048     switch (p_context->rc_status_cmd.pdu_id) {
2049     case AVRC_PDU_REGISTER_NOTIFICATION:
2050         rc_notification_interim_timout(p_context->rc_status_cmd.label);
2051         break;
2052
2053     case AVRC_PDU_GET_CAPABILITIES:
2054         avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2055         handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2056         break;
2057
2058     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2059         avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
2060         handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
2061         break;
2062
2063     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2064         avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
2065         handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
2066         break;
2067
2068     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2069         avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
2070         handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
2071         break;
2072
2073     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2074         avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
2075         handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
2076         break;
2077
2078     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2079         avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
2080         handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
2081         break;
2082
2083     case AVRC_PDU_GET_ELEMENT_ATTR:
2084         avrc_response.get_elem_attrs.status = BTIF_RC_STS_TIMEOUT;
2085         handle_get_elem_attr_response(&meta_msg, &avrc_response.get_elem_attrs);
2086         break;
2087
2088     case AVRC_PDU_GET_PLAY_STATUS:
2089         avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2090         handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2091         break;
2092     }
2093     release_transaction(p_context->rc_status_cmd.label);
2094 }
2095
2096 /***************************************************************************
2097 **
2098 ** Function         btif_rc_status_cmd_timer_timeout
2099 **
2100 ** Description      RC status command timeout callback.
2101 **                  This is called from BTU context and switches to BTIF
2102 **                  context to handle the timeout events
2103 ** Returns          None
2104 **
2105 ***************************************************************************/
2106 static void btif_rc_status_cmd_timer_timeout(void *data)
2107 {
2108     btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2109
2110     btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0,
2111                           (char *)p_data, sizeof(btif_rc_timer_context_t),
2112                           NULL);
2113 }
2114
2115 /***************************************************************************
2116 **
2117 ** Function         btif_rc_control_cmd_timeout_handler
2118 **
2119 ** Description      RC control command timeout handler (Runs in BTIF context).
2120 ** Returns          None
2121 **
2122 ***************************************************************************/
2123 static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2124                                                 char *data)
2125 {
2126     btif_rc_timer_context_t *p_context = (btif_rc_timer_context_t *)data;
2127     tAVRC_RESPONSE      avrc_response = {0};
2128     tBTA_AV_META_MSG    meta_msg;
2129
2130     memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2131     meta_msg.rc_handle = btif_rc_cb.rc_handle;
2132
2133     switch (p_context->rc_control_cmd.pdu_id) {
2134     case AVRC_PDU_SET_PLAYER_APP_VALUE:
2135         avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
2136         handle_set_app_attr_val_response(&meta_msg,
2137                                          &avrc_response.set_app_val);
2138         break;
2139     }
2140     release_transaction(p_context->rc_control_cmd.label);
2141 }
2142
2143 /***************************************************************************
2144 **
2145 ** Function         btif_rc_control_cmd_timer_timeout
2146 **
2147 ** Description      RC control command timeout callback.
2148 **                  This is called from BTU context and switches to BTIF
2149 **                  context to handle the timeout events
2150 ** Returns          None
2151 **
2152 ***************************************************************************/
2153 static void btif_rc_control_cmd_timer_timeout(void *data)
2154 {
2155     btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2156
2157     btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0,
2158                           (char *)p_data, sizeof(btif_rc_timer_context_t),
2159                           NULL);
2160 }
2161
2162 /***************************************************************************
2163 **
2164 ** Function         btif_rc_play_status_timeout_handler
2165 **
2166 ** Description      RC play status timeout handler (Runs in BTIF context).
2167 ** Returns          None
2168 **
2169 ***************************************************************************/
2170 static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event,
2171                                                 UNUSED_ATTR char *p_data)
2172 {
2173     get_play_status_cmd();
2174     rc_start_play_status_timer();
2175 }
2176
2177 /***************************************************************************
2178 **
2179 ** Function         btif_rc_play_status_timer_timeout
2180 **
2181 ** Description      RC play status timeout callback.
2182 **                  This is called from BTU context and switches to BTIF
2183 **                  context to handle the timeout events
2184 ** Returns          None
2185 **
2186 ***************************************************************************/
2187 static void btif_rc_play_status_timer_timeout(UNUSED_ATTR void *data)
2188 {
2189     btif_transfer_context(btif_rc_play_status_timeout_handler, 0, 0, 0, NULL);
2190 }
2191
2192 /***************************************************************************
2193 **
2194 ** Function         rc_start_play_status_timer
2195 **
2196 ** Description      Helper function to start the timer to fetch play status.
2197 ** Returns          None
2198 **
2199 ***************************************************************************/
2200 static void rc_start_play_status_timer(void)
2201 {
2202     /* Start the Play status timer only if it is not started */
2203     if (!alarm_is_scheduled(btif_rc_cb.rc_play_status_timer)) {
2204         if (btif_rc_cb.rc_play_status_timer == NULL) {
2205             btif_rc_cb.rc_play_status_timer =
2206                 alarm_new("btif_rc.rc_play_status_timer");
2207         }
2208         alarm_set_on_queue(btif_rc_cb.rc_play_status_timer,
2209                            BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2210                            btif_rc_play_status_timer_timeout, NULL,
2211                            btu_general_alarm_queue);
2212     }
2213 }
2214
2215 /***************************************************************************
2216 **
2217 ** Function         rc_stop_play_status_timer
2218 **
2219 ** Description      Helper function to stop the play status timer.
2220 ** Returns          None
2221 **
2222 ***************************************************************************/
2223 void rc_stop_play_status_timer()
2224 {
2225     if (btif_rc_cb.rc_play_status_timer != NULL)
2226         alarm_cancel(btif_rc_cb.rc_play_status_timer);
2227 }
2228
2229 /***************************************************************************
2230 **
2231 ** Function         register_for_event_notification
2232 **
2233 ** Description      Helper function registering notification events
2234 **                  sets an interim response timeout to handle if the remote
2235 **                  does not respond.
2236 ** Returns          None
2237 **
2238 ***************************************************************************/
2239 static void register_for_event_notification(btif_rc_supported_event_t *p_event)
2240 {
2241     bt_status_t status;
2242     rc_transaction_t *p_transaction;
2243
2244     status = get_transaction(&p_transaction);
2245     if (status == BT_STATUS_SUCCESS)
2246     {
2247         btif_rc_timer_context_t *p_context = &p_transaction->txn_timer_context;
2248
2249         status = register_notification_cmd (p_transaction->lbl, p_event->event_id, 0);
2250         if (status != BT_STATUS_SUCCESS)
2251         {
2252             BTIF_TRACE_ERROR("%s Error in Notification registration %d",
2253                 __FUNCTION__, status);
2254             release_transaction (p_transaction->lbl);
2255             return;
2256         }
2257         p_event->label = p_transaction->lbl;
2258         p_event->status = eREGISTERED;
2259         p_context->rc_status_cmd.label = p_transaction->lbl;
2260         p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
2261
2262         alarm_free(p_transaction->txn_timer);
2263         p_transaction->txn_timer =
2264             alarm_new("btif_rc.status_command_txn_timer");
2265         alarm_set_on_queue(p_transaction->txn_timer,
2266                            BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2267                            btif_rc_status_cmd_timer_timeout, p_context,
2268                            btu_general_alarm_queue);
2269     }
2270     else
2271     {
2272         BTIF_TRACE_ERROR("%s Error No more Transaction label %d",
2273             __FUNCTION__, status);
2274     }
2275 }
2276
2277 static void start_status_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2278 {
2279     btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2280     p_context->rc_status_cmd.label = p_txn->lbl;
2281     p_context->rc_status_cmd.pdu_id = pdu_id;
2282
2283     alarm_free(p_txn->txn_timer);
2284     p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
2285     alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
2286                        btif_rc_status_cmd_timer_timeout, p_context,
2287                        btu_general_alarm_queue);
2288 }
2289
2290 static void start_control_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2291 {
2292     btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2293     p_context->rc_control_cmd.label = p_txn->lbl;
2294     p_context->rc_control_cmd.pdu_id = pdu_id;
2295
2296     alarm_free(p_txn->txn_timer);
2297     p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer");
2298     alarm_set_on_queue(p_txn->txn_timer,
2299                        BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
2300                        btif_rc_control_cmd_timer_timeout, p_context,
2301                        btu_general_alarm_queue);
2302 }
2303
2304 /***************************************************************************
2305 **
2306 ** Function         handle_get_capability_response
2307 **
2308 ** Description      Handles the get_cap_response to populate company id info
2309 **                  and query the supported events.
2310 **                  Initiates Notification registration for events supported
2311 ** Returns          None
2312 **
2313 ***************************************************************************/
2314 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp)
2315 {
2316     int xx = 0;
2317
2318     /* Todo: Do we need to retry on command timeout */
2319     if (p_rsp->status != AVRC_STS_NO_ERROR)
2320     {
2321         BTIF_TRACE_ERROR("%s Error capability response 0x%02X",
2322                 __FUNCTION__, p_rsp->status);
2323         return;
2324     }
2325
2326     if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED)
2327     {
2328         btif_rc_supported_event_t *p_event;
2329
2330         /* Todo: Check if list can be active when we hit here */
2331         btif_rc_cb.rc_supported_event_list = list_new(osi_free);
2332         for (xx = 0; xx < p_rsp->count; xx++)
2333         {
2334             /* Skip registering for Play position change notification */
2335             if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE)||
2336                 (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE)||
2337                 (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE))
2338             {
2339                 p_event = (btif_rc_supported_event_t *)osi_malloc(sizeof(btif_rc_supported_event_t));
2340                 p_event->event_id = p_rsp->param.event_id[xx];
2341                 p_event->status = eNOT_REGISTERED;
2342                 list_append(btif_rc_cb.rc_supported_event_list, p_event);
2343             }
2344         }
2345         p_event = list_front(btif_rc_cb.rc_supported_event_list);
2346         if (p_event != NULL)
2347         {
2348             register_for_event_notification(p_event);
2349         }
2350     }
2351     else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
2352     {
2353         getcapabilities_cmd (AVRC_CAP_EVENTS_SUPPORTED);
2354         BTIF_TRACE_EVENT("%s AVRC_CAP_COMPANY_ID: ", __FUNCTION__);
2355         for (xx = 0; xx < p_rsp->count; xx++)
2356         {
2357             BTIF_TRACE_EVENT("%s    : %d", __FUNCTION__, p_rsp->param.company_id[xx]);
2358         }
2359     }
2360 }
2361
2362 bool rc_is_track_id_valid (tAVRC_UID uid)
2363 {
2364     tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2365
2366     if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0)
2367     {
2368         return false;
2369     }
2370     else
2371     {
2372         return true;
2373     }
2374 }
2375
2376 /***************************************************************************
2377 **
2378 ** Function         handle_notification_response
2379 **
2380 ** Description      Main handler for notification responses to registered events
2381 **                  1. Register for unregistered event(in interim response path)
2382 **                  2. After registering for all supported events, start
2383 **                     retrieving application settings and values
2384 **                  3. Reregister for events on getting changed response
2385 **                  4. Run play status timer for getting position when the
2386 **                     status changes to playing
2387 **                  5. Get the Media details when the track change happens
2388 **                     or track change interim response is received with
2389 **                     valid track id
2390 **                  6. HAL callback for play status change and application
2391 **                     setting change
2392 ** Returns          None
2393 **
2394 ***************************************************************************/
2395 static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG_NOTIF_RSP *p_rsp)
2396 {
2397     bt_bdaddr_t rc_addr;
2398     UINT32 attr_list[] = {
2399         AVRC_MEDIA_ATTR_ID_TITLE,
2400         AVRC_MEDIA_ATTR_ID_ARTIST,
2401         AVRC_MEDIA_ATTR_ID_ALBUM,
2402         AVRC_MEDIA_ATTR_ID_TRACK_NUM,
2403         AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
2404         AVRC_MEDIA_ATTR_ID_GENRE,
2405         AVRC_MEDIA_ATTR_ID_PLAYING_TIME
2406         };
2407
2408
2409     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2410
2411     if (pmeta_msg->code == AVRC_RSP_INTERIM)
2412     {
2413         btif_rc_supported_event_t *p_event;
2414         list_node_t *node;
2415
2416         BTIF_TRACE_DEBUG("%s Interim response : 0x%2X ", __FUNCTION__, p_rsp->event_id);
2417         switch (p_rsp->event_id)
2418         {
2419             case AVRC_EVT_PLAY_STATUS_CHANGE:
2420                 /* Start timer to get play status periodically
2421                  * if the play state is playing.
2422                  */
2423                 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2424                 {
2425                     rc_start_play_status_timer();
2426                 }
2427                 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2428                     &rc_addr, p_rsp->param.play_status);
2429                 break;
2430
2431             case AVRC_EVT_TRACK_CHANGE:
2432                 if (rc_is_track_id_valid (p_rsp->param.track) != true)
2433                 {
2434                     break;
2435                 }
2436                 else
2437                 {
2438                     UINT8 *p_data = p_rsp->param.track;
2439                     /* Update the UID for current track
2440                      * Attributes will be fetched after the AVRCP procedure
2441                      */
2442                     BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data);
2443                 }
2444                 break;
2445
2446             case AVRC_EVT_APP_SETTING_CHANGE:
2447                 break;
2448
2449             case AVRC_EVT_NOW_PLAYING_CHANGE:
2450                 break;
2451
2452             case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2453                 break;
2454
2455             case AVRC_EVT_ADDR_PLAYER_CHANGE:
2456                 break;
2457
2458             case AVRC_EVT_UIDS_CHANGE:
2459                 break;
2460
2461             case AVRC_EVT_TRACK_REACHED_END:
2462             case AVRC_EVT_TRACK_REACHED_START:
2463             case AVRC_EVT_PLAY_POS_CHANGED:
2464             case AVRC_EVT_BATTERY_STATUS_CHANGE:
2465             case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2466             default:
2467                 BTIF_TRACE_ERROR("%s  Unhandled interim response 0x%2X", __FUNCTION__,
2468                     p_rsp->event_id);
2469                 return;
2470         }
2471         list_foreach(btif_rc_cb.rc_supported_event_list,
2472                 iterate_supported_event_list_for_interim_rsp,
2473                 &p_rsp->event_id);
2474
2475         node = list_begin(btif_rc_cb.rc_supported_event_list);
2476         while (node != NULL)
2477         {
2478             p_event = (btif_rc_supported_event_t *)list_node(node);
2479             if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2480             {
2481                 register_for_event_notification(p_event);
2482                 break;
2483             }
2484             node = list_next (node);
2485             p_event = NULL;
2486         }
2487         /* Registered for all events, we can request application settings */
2488         if ((p_event == NULL) && (btif_rc_cb.rc_app_settings.query_started == false))
2489         {
2490             /* we need to do this only if remote TG supports
2491              * player application settings
2492              */
2493             btif_rc_cb.rc_app_settings.query_started = TRUE;
2494             if (btif_rc_cb.rc_features & BTA_AV_FEAT_APP_SETTING)
2495             {
2496                 list_player_app_setting_attrib_cmd();
2497             }
2498             else
2499             {
2500                 BTIF_TRACE_DEBUG("%s App setting not supported, complete procedure", __FUNCTION__);
2501                 rc_ctrl_procedure_complete();
2502             }
2503         }
2504     }
2505     else if (pmeta_msg->code == AVRC_RSP_CHANGED)
2506     {
2507         btif_rc_supported_event_t *p_event;
2508         list_node_t *node;
2509
2510         BTIF_TRACE_DEBUG("%s Notification completed : 0x%2X ", __FUNCTION__,
2511             p_rsp->event_id);
2512
2513         node = list_begin(btif_rc_cb.rc_supported_event_list);
2514         while (node != NULL)
2515         {
2516             p_event = (btif_rc_supported_event_t *)list_node(node);
2517             if ((p_event != NULL) && (p_event->event_id == p_rsp->event_id))
2518             {
2519                 p_event->status = eNOT_REGISTERED;
2520                 register_for_event_notification(p_event);
2521                 break;
2522             }
2523             node = list_next (node);
2524         }
2525
2526         switch (p_rsp->event_id)
2527         {
2528             case AVRC_EVT_PLAY_STATUS_CHANGE:
2529                 /* Start timer to get play status periodically
2530                  * if the play state is playing.
2531                  */
2532                 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2533                 {
2534                     rc_start_play_status_timer();
2535                 }
2536                 else
2537                 {
2538                     rc_stop_play_status_timer();
2539                 }
2540                 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2541                     &rc_addr, p_rsp->param.play_status);
2542                 break;
2543
2544             case AVRC_EVT_TRACK_CHANGE:
2545                 if (rc_is_track_id_valid (p_rsp->param.track) != true)
2546                 {
2547                     break;
2548                 }
2549                 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
2550                 break;
2551
2552             case AVRC_EVT_APP_SETTING_CHANGE:
2553             {
2554                 btrc_player_settings_t app_settings;
2555                 UINT16 xx;
2556
2557                 app_settings.num_attr = p_rsp->param.player_setting.num_attr;
2558                 for (xx = 0; xx < app_settings.num_attr; xx++)
2559                 {
2560                     app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
2561                     app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
2562                 }
2563                 HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2564                     &rc_addr, &app_settings);
2565             }
2566                 break;
2567
2568             case AVRC_EVT_NOW_PLAYING_CHANGE:
2569                 break;
2570
2571             case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2572                 break;
2573
2574             case AVRC_EVT_ADDR_PLAYER_CHANGE:
2575                 break;
2576
2577             case AVRC_EVT_UIDS_CHANGE:
2578                 break;
2579
2580             case AVRC_EVT_TRACK_REACHED_END:
2581             case AVRC_EVT_TRACK_REACHED_START:
2582             case AVRC_EVT_PLAY_POS_CHANGED:
2583             case AVRC_EVT_BATTERY_STATUS_CHANGE:
2584             case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2585             default:
2586                 BTIF_TRACE_ERROR("%s  Unhandled completion response 0x%2X",
2587                     __FUNCTION__, p_rsp->event_id);
2588                 return;
2589         }
2590     }
2591 }
2592
2593 /***************************************************************************
2594 **
2595 ** Function         handle_app_attr_response
2596 **
2597 ** Description      handles the the application attributes response and
2598 **                  initiates procedure to fetch the attribute values
2599 ** Returns          None
2600 **
2601 ***************************************************************************/
2602 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp)
2603 {
2604     UINT8 xx;
2605
2606     if (p_rsp->status != AVRC_STS_NO_ERROR)
2607     {
2608         BTIF_TRACE_ERROR("%s Error getting Player application settings: 0x%2X",
2609                 __FUNCTION__, p_rsp->status);
2610         rc_ctrl_procedure_complete();
2611         return;
2612     }
2613
2614     for (xx = 0; xx < p_rsp->num_attr; xx++)
2615     {
2616         UINT8 st_index;
2617
2618         if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT)
2619         {
2620             st_index = btif_rc_cb.rc_app_settings.num_ext_attrs;
2621             btif_rc_cb.rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
2622             btif_rc_cb.rc_app_settings.num_ext_attrs++;
2623         }
2624         else
2625         {
2626             st_index = btif_rc_cb.rc_app_settings.num_attrs;
2627             btif_rc_cb.rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
2628             btif_rc_cb.rc_app_settings.num_attrs++;
2629         }
2630     }
2631     btif_rc_cb.rc_app_settings.attr_index = 0;
2632     btif_rc_cb.rc_app_settings.ext_attr_index = 0;
2633     btif_rc_cb.rc_app_settings.ext_val_index = 0;
2634     if (p_rsp->num_attr)
2635     {
2636         list_player_app_setting_value_cmd (btif_rc_cb.rc_app_settings.attrs[0].attr_id);
2637     }
2638     else
2639     {
2640         BTIF_TRACE_ERROR("%s No Player application settings found",
2641                 __FUNCTION__);
2642     }
2643 }
2644
2645 /***************************************************************************
2646 **
2647 ** Function         handle_app_val_response
2648 **
2649 ** Description      handles the the attributes value response and if extended
2650 **                  menu is available, it initiates query for the attribute
2651 **                  text. If not, it initiates procedure to get the current
2652 **                  attribute values and calls the HAL callback for provding
2653 **                  application settings information.
2654 ** Returns          None
2655 **
2656 ***************************************************************************/
2657 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp)
2658 {
2659     UINT8 xx, attr_index;
2660     UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2661     btif_rc_player_app_settings_t *p_app_settings;
2662     bt_bdaddr_t rc_addr;
2663
2664     /* Todo: Do we need to retry on command timeout */
2665     if (p_rsp->status != AVRC_STS_NO_ERROR)
2666     {
2667         BTIF_TRACE_ERROR("%s Error fetching attribute values 0x%02X",
2668                 __FUNCTION__, p_rsp->status);
2669         return;
2670     }
2671
2672     p_app_settings = &btif_rc_cb.rc_app_settings;
2673     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2674
2675     if (p_app_settings->attr_index < p_app_settings->num_attrs)
2676     {
2677         attr_index = p_app_settings->attr_index;
2678         p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
2679         for (xx = 0; xx < p_rsp->num_val; xx++)
2680         {
2681             p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
2682         }
2683         attr_index++;
2684         p_app_settings->attr_index++;
2685         if (attr_index < p_app_settings->num_attrs)
2686         {
2687             list_player_app_setting_value_cmd (p_app_settings->attrs[p_app_settings->attr_index].attr_id);
2688         }
2689         else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2690         {
2691             attr_index = 0;
2692             p_app_settings->ext_attr_index = 0;
2693             list_player_app_setting_value_cmd (p_app_settings->ext_attrs[attr_index].attr_id);
2694         }
2695         else
2696         {
2697             for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2698             {
2699                 attrs[xx] = p_app_settings->attrs[xx].attr_id;
2700             }
2701             get_player_app_setting_cmd (p_app_settings->num_attrs, attrs);
2702             HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2703                         p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2704         }
2705     }
2706     else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2707     {
2708         attr_index = p_app_settings->ext_attr_index;
2709         p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
2710         for (xx = 0; xx < p_rsp->num_val; xx++)
2711         {
2712             p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
2713         }
2714         attr_index++;
2715         p_app_settings->ext_attr_index++;
2716         if (attr_index < p_app_settings->num_ext_attrs)
2717         {
2718             list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id);
2719         }
2720         else
2721         {
2722             UINT8 attr[AVRC_MAX_APP_ATTR_SIZE];
2723             UINT8 xx;
2724
2725             for (xx = 0; xx < p_app_settings->num_ext_attrs; xx++)
2726             {
2727                 attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
2728             }
2729             get_player_app_setting_attr_text_cmd(attr, xx);
2730         }
2731     }
2732 }
2733
2734 /***************************************************************************
2735 **
2736 ** Function         handle_app_cur_val_response
2737 **
2738 ** Description      handles the the get attributes value response.
2739 **
2740 ** Returns          None
2741 **
2742 ***************************************************************************/
2743 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp)
2744 {
2745     btrc_player_settings_t app_settings;
2746     bt_bdaddr_t rc_addr;
2747     UINT16 xx;
2748
2749     /* Todo: Do we need to retry on command timeout */
2750     if (p_rsp->status != AVRC_STS_NO_ERROR)
2751     {
2752         BTIF_TRACE_ERROR("%s Error fetching current settings: 0x%02X",
2753                 __FUNCTION__, p_rsp->status);
2754         return;
2755     }
2756
2757     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2758
2759     app_settings.num_attr = p_rsp->num_val;
2760     for (xx = 0; xx < app_settings.num_attr; xx++)
2761     {
2762         app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
2763         app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
2764     }
2765     HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2766         &rc_addr, &app_settings);
2767     /* Application settings are fetched only once for initial values
2768      * initiate anything that follows after RC procedure.
2769      * Defer it if browsing is supported till players query
2770      */
2771     rc_ctrl_procedure_complete ();
2772     osi_free_and_reset((void **)&p_rsp->p_vals);
2773 }
2774
2775 /***************************************************************************
2776 **
2777 ** Function         handle_app_attr_txt_response
2778 **
2779 ** Description      handles the the get attributes text response, if fails
2780 **                  calls HAL callback with just normal settings and initiates
2781 **                  query for current settings else initiates query for value text
2782 ** Returns          None
2783 **
2784 ***************************************************************************/
2785 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2786 {
2787     UINT8 xx;
2788     UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2789     btif_rc_player_app_settings_t *p_app_settings;
2790     bt_bdaddr_t rc_addr;
2791
2792     p_app_settings = &btif_rc_cb.rc_app_settings;
2793     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2794
2795     /* Todo: Do we need to retry on command timeout */
2796     if (p_rsp->status != AVRC_STS_NO_ERROR)
2797     {
2798         UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2799
2800         BTIF_TRACE_ERROR("%s Error fetching attribute text: 0x%02X",
2801                 __FUNCTION__, p_rsp->status);
2802         /* Not able to fetch Text for extended Menu, skip the process
2803          * and cleanup used memory. Proceed to get the current settings
2804          * for standard attributes.
2805          */
2806         p_app_settings->num_ext_attrs = 0;
2807         for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2808             osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2809         p_app_settings->ext_attr_index = 0;
2810
2811         for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2812         {
2813             attrs[xx] = p_app_settings->attrs[xx].attr_id;
2814         }
2815         HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2816                     p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2817
2818         get_player_app_setting_cmd (xx, attrs);
2819         return;
2820     }
2821
2822     for (xx = 0; xx < p_rsp->num_attr; xx++)
2823     {
2824         UINT8 x;
2825         for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2826         {
2827             if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id)
2828             {
2829                 p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2830                 p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
2831                 p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
2832                 break;
2833             }
2834         }
2835     }
2836
2837     for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++)
2838     {
2839         vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
2840     }
2841     get_player_app_setting_value_text_cmd(vals, xx);
2842 }
2843
2844
2845 /***************************************************************************
2846 **
2847 ** Function         handle_app_attr_val_txt_response
2848 **
2849 ** Description      handles the the get attributes value text response, if fails
2850 **                  calls HAL callback with just normal settings and initiates
2851 **                  query for current settings
2852 ** Returns          None
2853 **
2854 ***************************************************************************/
2855 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2856 {
2857     UINT8 xx, attr_index;
2858     UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2859     UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2860     btif_rc_player_app_settings_t *p_app_settings;
2861     bt_bdaddr_t rc_addr;
2862
2863     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2864     p_app_settings = &btif_rc_cb.rc_app_settings;
2865
2866     /* Todo: Do we need to retry on command timeout */
2867     if (p_rsp->status != AVRC_STS_NO_ERROR)
2868     {
2869         UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2870
2871         BTIF_TRACE_ERROR("%s Error fetching attribute value text: 0x%02X",
2872                 __FUNCTION__, p_rsp->status);
2873
2874         /* Not able to fetch Text for extended Menu, skip the process
2875          * and cleanup used memory. Proceed to get the current settings
2876          * for standard attributes.
2877          */
2878         p_app_settings->num_ext_attrs = 0;
2879         for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2880         {
2881             int x;
2882             btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2883
2884             for (x = 0; x < p_ext_attr->num_val; x++)
2885                 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2886             p_ext_attr->num_val = 0;
2887             osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2888         }
2889         p_app_settings->ext_attr_index = 0;
2890
2891         for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2892         {
2893             attrs[xx] = p_app_settings->attrs[xx].attr_id;
2894         }
2895         HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2896                     p_app_settings->num_attrs, p_app_settings->attrs, 0, NULL);
2897
2898         get_player_app_setting_cmd (xx, attrs);
2899         return;
2900     }
2901
2902     for (xx = 0; xx < p_rsp->num_attr; xx++)
2903     {
2904         UINT8 x;
2905         btrc_player_app_ext_attr_t *p_ext_attr;
2906         p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
2907         for (x = 0; x < p_rsp->num_attr; x++)
2908         {
2909             if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id)
2910             {
2911                 p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2912                 p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
2913                 p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
2914                 break;
2915             }
2916         }
2917     }
2918     p_app_settings->ext_val_index++;
2919
2920     if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs)
2921     {
2922         attr_index = p_app_settings->ext_val_index;
2923         for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++)
2924         {
2925             vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
2926         }
2927         get_player_app_setting_value_text_cmd(vals, xx);
2928     }
2929     else
2930     {
2931         UINT8 x;
2932
2933         for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2934         {
2935             attrs[xx] = p_app_settings->attrs[xx].attr_id;
2936         }
2937         for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2938         {
2939             attrs[xx+x] = p_app_settings->ext_attrs[x].attr_id;
2940         }
2941         HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2942                     p_app_settings->num_attrs, p_app_settings->attrs,
2943                     p_app_settings->num_ext_attrs, p_app_settings->ext_attrs);
2944         get_player_app_setting_cmd (xx + x, attrs);
2945
2946         /* Free the application settings information after sending to
2947          * application.
2948          */
2949         for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2950         {
2951             int x;
2952             btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2953
2954             for (x = 0; x < p_ext_attr->num_val; x++)
2955                 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2956             p_ext_attr->num_val = 0;
2957             osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2958         }
2959         p_app_settings->num_attrs = 0;
2960     }
2961 }
2962
2963 /***************************************************************************
2964 **
2965 ** Function         handle_set_app_attr_val_response
2966 **
2967 ** Description      handles the the set attributes value response, if fails
2968 **                  calls HAL callback to indicate the failure
2969 ** Returns          None
2970 **
2971 ***************************************************************************/
2972 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp)
2973 {
2974     uint8_t accepted = 0;
2975     bt_bdaddr_t rc_addr;
2976
2977     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2978
2979     /* For timeout pmeta_msg will be NULL, else we need to
2980      * check if this is accepted by TG
2981      */
2982     if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT))
2983     {
2984         accepted = 1;
2985     }
2986     HAL_CBACK(bt_rc_ctrl_callbacks, setplayerappsetting_rsp_cb, &rc_addr, accepted);
2987 }
2988
2989 /***************************************************************************
2990 **
2991 ** Function         handle_get_elem_attr_response
2992 **
2993 ** Description      handles the the element attributes response, calls
2994 **                  HAL callback to update track change information.
2995 ** Returns          None
2996 **
2997 ***************************************************************************/
2998 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg,
2999                                            tAVRC_GET_ELEM_ATTRS_RSP *p_rsp)
3000 {
3001     if (p_rsp->status == AVRC_STS_NO_ERROR) {
3002         bt_bdaddr_t rc_addr;
3003         size_t buf_size = p_rsp->num_attr * sizeof(btrc_element_attr_val_t);
3004         btrc_element_attr_val_t *p_attr =
3005             (btrc_element_attr_val_t *)osi_calloc(buf_size);
3006
3007         bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3008
3009         for (int i = 0; i < p_rsp->num_attr; i++) {
3010             p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
3011             /* Todo. Legth limit check to include null */
3012             if (p_rsp->p_attrs[i].name.str_len &&
3013                 p_rsp->p_attrs[i].name.p_str) {
3014                 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str,
3015                        p_rsp->p_attrs[i].name.str_len);
3016                 osi_free_and_reset((void **)&p_rsp->p_attrs[i].name.p_str);
3017             }
3018         }
3019         HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb,
3020                   &rc_addr, p_rsp->num_attr, p_attr);
3021         osi_free(p_attr);
3022     } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
3023         /* Retry for timeout case, this covers error handling
3024          * for continuation failure also.
3025          */
3026         UINT32 attr_list[] = {
3027             AVRC_MEDIA_ATTR_ID_TITLE,
3028             AVRC_MEDIA_ATTR_ID_ARTIST,
3029             AVRC_MEDIA_ATTR_ID_ALBUM,
3030             AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3031             AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
3032             AVRC_MEDIA_ATTR_ID_GENRE,
3033             AVRC_MEDIA_ATTR_ID_PLAYING_TIME
3034             };
3035         get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
3036     } else {
3037         BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d",
3038                          __func__, p_rsp->status);
3039     }
3040 }
3041
3042 /***************************************************************************
3043 **
3044 ** Function         handle_get_playstatus_response
3045 **
3046 ** Description      handles the the play status response, calls
3047 **                  HAL callback to update play position.
3048 ** Returns          None
3049 **
3050 ***************************************************************************/
3051 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp)
3052 {
3053     bt_bdaddr_t rc_addr;
3054
3055     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3056
3057     if (p_rsp->status == AVRC_STS_NO_ERROR)
3058     {
3059         HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb,
3060             &rc_addr, p_rsp->song_len, p_rsp->song_pos);
3061     }
3062     else
3063     {
3064         BTIF_TRACE_ERROR("%s: Error in get play status procedure %d",
3065             __FUNCTION__, p_rsp->status);
3066     }
3067 }
3068
3069 /***************************************************************************
3070 **
3071 ** Function         clear_cmd_timeout
3072 **
3073 ** Description      helper function to stop the command timeout timer
3074 ** Returns          None
3075 **
3076 ***************************************************************************/
3077 static void clear_cmd_timeout (UINT8 label)
3078 {
3079     rc_transaction_t *p_txn;
3080
3081     p_txn = get_transaction_by_lbl (label);
3082     if (p_txn == NULL)
3083     {
3084         BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__);
3085         return;
3086     }
3087
3088     if (p_txn->txn_timer != NULL)
3089         alarm_cancel(p_txn->txn_timer);
3090 }
3091
3092 /***************************************************************************
3093 **
3094 ** Function         handle_avk_rc_metamsg_rsp
3095 **
3096 ** Description      Handle RC metamessage response
3097 **
3098 ** Returns          void
3099 **
3100 ***************************************************************************/
3101 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
3102 {
3103     tAVRC_RESPONSE    avrc_response = {0};
3104     UINT8             scratch_buf[512] = {0};// this variable is unused
3105     UINT16            buf_len;
3106     tAVRC_STS         status;
3107
3108     BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ", __FUNCTION__,
3109                         pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
3110
3111     if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&&
3112                 (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&&
3113                 (pmeta_msg->code <= AVRC_RSP_INTERIM))
3114     {
3115         status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
3116         BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d",
3117                          __FUNCTION__, status, avrc_response.pdu,
3118                          pmeta_msg->p_msg->vendor.hdr.ctype);
3119
3120         switch (avrc_response.pdu)
3121         {
3122             case AVRC_PDU_REGISTER_NOTIFICATION:
3123                 handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
3124                 if (pmeta_msg->code == AVRC_RSP_INTERIM)
3125                 {
3126                     /* Don't free the transaction Id */
3127                     clear_cmd_timeout (pmeta_msg->label);
3128                     return;
3129                 }
3130                 break;
3131
3132             case AVRC_PDU_GET_CAPABILITIES:
3133                 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
3134                 break;
3135
3136             case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3137                 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
3138                 break;
3139
3140             case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3141                 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
3142                 break;
3143
3144             case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3145                 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
3146                 break;
3147
3148             case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3149                 handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
3150                 break;
3151
3152             case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3153                 handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
3154                 break;
3155
3156             case AVRC_PDU_SET_PLAYER_APP_VALUE:
3157                 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
3158                 break;
3159
3160             case AVRC_PDU_GET_ELEMENT_ATTR:
3161                 handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs);
3162                 break;
3163
3164             case AVRC_PDU_GET_PLAY_STATUS:
3165                 handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
3166                 break;
3167         }
3168         release_transaction(pmeta_msg->label);
3169     }
3170     else
3171     {
3172         BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3173             __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3174         return;
3175     }
3176 }
3177
3178 /***************************************************************************
3179 **
3180 ** Function         handle_avk_rc_metamsg_cmd
3181 **
3182 ** Description      Handle RC metamessage response
3183 **
3184 ** Returns          void
3185 **
3186 ***************************************************************************/
3187 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg)
3188 {
3189     tAVRC_COMMAND    avrc_cmd = {0};
3190     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3191     BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ",__FUNCTION__,
3192                      pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code);
3193     if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&&
3194                 (pmeta_msg->code <= AVRC_CMD_GEN_INQ))
3195     {
3196         status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
3197         BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
3198                          __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
3199
3200         if (status != AVRC_STS_NO_ERROR)
3201         {
3202             /* return error */
3203             BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
3204                 __FUNCTION__, status);
3205             send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status);
3206         }
3207         else
3208         {
3209             if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
3210             {
3211                 UINT8 event_id = avrc_cmd.reg_notif.event_id;
3212                 BTIF_TRACE_EVENT("%s:Register notification event_id: %s",
3213                         __FUNCTION__, dump_rc_notification_event_id(event_id));
3214             }
3215             else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME)
3216             {
3217                 BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__);
3218             }
3219             btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label);
3220         }
3221     }
3222     else
3223     {
3224       BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3225                        __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3226         return;
3227     }
3228 }
3229 #endif
3230
3231 /***************************************************************************
3232 **
3233 ** Function         cleanup
3234 **
3235 ** Description      Closes the AVRC interface
3236 **
3237 ** Returns          void
3238 **
3239 ***************************************************************************/
3240 static void cleanup()
3241 {
3242     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3243     close_uinput();
3244     if (bt_rc_callbacks)
3245     {
3246         bt_rc_callbacks = NULL;
3247     }
3248     alarm_free(btif_rc_cb.rc_play_status_timer);
3249     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3250     lbl_destroy();
3251     BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3252 }
3253
3254 /***************************************************************************
3255 **
3256 ** Function         cleanup_ctrl
3257 **
3258 ** Description      Closes the AVRC Controller interface
3259 **
3260 ** Returns          void
3261 **
3262 ***************************************************************************/
3263 static void cleanup_ctrl()
3264 {
3265     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3266
3267     if (bt_rc_ctrl_callbacks)
3268     {
3269         bt_rc_ctrl_callbacks = NULL;
3270     }
3271     alarm_free(btif_rc_cb.rc_play_status_timer);
3272     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3273     lbl_destroy();
3274     BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3275 }
3276
3277 /***************************************************************************
3278 **
3279 ** Function         getcapabilities_cmd
3280 **
3281 ** Description      GetCapabilties from Remote(Company_ID, Events_Supported)
3282 **
3283 ** Returns          void
3284 **
3285 ***************************************************************************/
3286 static bt_status_t getcapabilities_cmd (uint8_t cap_id)
3287 {
3288     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3289     rc_transaction_t *p_transaction = NULL;
3290 #if (AVRC_CTLR_INCLUDED == TRUE)
3291     BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id);
3292     CHECK_RC_CONNECTED
3293     bt_status_t tran_status=get_transaction(&p_transaction);
3294     if (BT_STATUS_SUCCESS != tran_status)
3295         return BT_STATUS_FAIL;
3296
3297      tAVRC_COMMAND avrc_cmd = {0};
3298      BT_HDR *p_msg = NULL;
3299      avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
3300      avrc_cmd.get_caps.capability_id = cap_id;
3301      avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
3302      avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
3303      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3304      if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3305      {
3306          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3307          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3308                             __FUNCTION__,p_transaction->lbl);
3309          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3310                                                           data_start, p_msg->len);
3311          status =  BT_STATUS_SUCCESS;
3312          start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction);
3313      }
3314      else
3315      {
3316          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3317                              __FUNCTION__, status);
3318      }
3319      osi_free(p_msg);
3320 #else
3321     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3322 #endif
3323     return status;
3324 }
3325
3326 /***************************************************************************
3327 **
3328 ** Function         list_player_app_setting_attrib_cmd
3329 **
3330 ** Description      Get supported List Player Attributes
3331 **
3332 ** Returns          void
3333 **
3334 ***************************************************************************/
3335 static bt_status_t list_player_app_setting_attrib_cmd(void)
3336 {
3337     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3338     rc_transaction_t *p_transaction = NULL;
3339 #if (AVRC_CTLR_INCLUDED == TRUE)
3340     BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3341     CHECK_RC_CONNECTED
3342     bt_status_t tran_status=get_transaction(&p_transaction);
3343     if (BT_STATUS_SUCCESS != tran_status)
3344         return BT_STATUS_FAIL;
3345
3346      tAVRC_COMMAND avrc_cmd = {0};
3347      BT_HDR *p_msg = NULL;
3348      avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
3349      avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
3350      avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
3351      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3352      if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3353      {
3354          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3355          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3356                             __FUNCTION__,p_transaction->lbl);
3357          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3358                                                           data_start, p_msg->len);
3359          status =  BT_STATUS_SUCCESS;
3360          start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction);
3361      }
3362      else
3363      {
3364
3365          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3366                             __FUNCTION__, status);
3367      }
3368      osi_free(p_msg);
3369 #else
3370     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3371 #endif
3372     return status;
3373 }
3374
3375 /***************************************************************************
3376 **
3377 ** Function         list_player_app_setting_value_cmd
3378 **
3379 ** Description      Get values of supported Player Attributes
3380 **
3381 ** Returns          void
3382 **
3383 ***************************************************************************/
3384 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id)
3385 {
3386     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3387     rc_transaction_t *p_transaction=NULL;
3388 #if (AVRC_CTLR_INCLUDED == TRUE)
3389     BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id);
3390     CHECK_RC_CONNECTED
3391     bt_status_t tran_status=get_transaction(&p_transaction);
3392     if (BT_STATUS_SUCCESS != tran_status)
3393         return BT_STATUS_FAIL;
3394
3395      tAVRC_COMMAND avrc_cmd = {0};
3396      BT_HDR *p_msg = NULL;
3397      avrc_cmd.list_app_values.attr_id = attrib_id;
3398      avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
3399      avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
3400      avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
3401      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3402      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3403      {
3404          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3405          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3406                             __FUNCTION__,p_transaction->lbl);
3407          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3408                                data_start, p_msg->len);
3409          status =  BT_STATUS_SUCCESS;
3410          start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction);
3411      }
3412      else
3413      {
3414          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3415      }
3416      osi_free(p_msg);
3417 #else
3418     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3419 #endif
3420     return status;
3421 }
3422
3423 /***************************************************************************
3424 **
3425 ** Function         get_player_app_setting_cmd
3426 **
3427 ** Description      Get current values of Player Attributes
3428 **
3429 ** Returns          void
3430 **
3431 ***************************************************************************/
3432 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids)
3433 {
3434     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3435     rc_transaction_t *p_transaction = NULL;
3436     int count  = 0;
3437 #if (AVRC_CTLR_INCLUDED == TRUE)
3438     BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3439     CHECK_RC_CONNECTED
3440     bt_status_t tran_status=get_transaction(&p_transaction);
3441     if (BT_STATUS_SUCCESS != tran_status)
3442         return BT_STATUS_FAIL;
3443
3444      tAVRC_COMMAND avrc_cmd = {0};
3445      BT_HDR *p_msg = NULL;
3446      avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
3447      avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
3448      avrc_cmd.get_cur_app_val.num_attr = num_attrib;
3449      avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
3450
3451      for (count = 0; count < num_attrib; count++)
3452      {
3453          avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
3454      }
3455      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3456      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3457      {
3458          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3459          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3460                             __FUNCTION__,p_transaction->lbl);
3461          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3462                           data_start, p_msg->len);
3463          status =  BT_STATUS_SUCCESS;
3464          start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction);
3465      }
3466      else
3467      {
3468          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3469                             __FUNCTION__, status);
3470      }
3471      osi_free(p_msg);
3472 #else
3473     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3474 #endif
3475     return status;
3476 }
3477
3478 /***************************************************************************
3479 **
3480 ** Function         change_player_app_setting
3481 **
3482 ** Description      Set current values of Player Attributes
3483 **
3484 ** Returns          void
3485 **
3486 ***************************************************************************/
3487 static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals)
3488 {
3489     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3490     rc_transaction_t *p_transaction = NULL;
3491     int count  = 0;
3492 #if (AVRC_CTLR_INCLUDED == TRUE)
3493     BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3494     CHECK_RC_CONNECTED
3495     bt_status_t tran_status=get_transaction(&p_transaction);
3496     if (BT_STATUS_SUCCESS != tran_status)
3497         return BT_STATUS_FAIL;
3498
3499      tAVRC_COMMAND avrc_cmd = {0};
3500      BT_HDR *p_msg = NULL;
3501      avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
3502      avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
3503      avrc_cmd.set_app_val.num_val = num_attrib;
3504      avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
3505      avrc_cmd.set_app_val.p_vals =
3506            (tAVRC_APP_SETTING *)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
3507      for (count = 0; count < num_attrib; count++)
3508      {
3509          avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
3510          avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
3511      }
3512      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3513      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3514      {
3515          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3516          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3517                             __FUNCTION__,p_transaction->lbl);
3518          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_CTRL,
3519                               data_start, p_msg->len);
3520          status =  BT_STATUS_SUCCESS;
3521          start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction);
3522      }
3523      else
3524      {
3525          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3526                             __FUNCTION__, status);
3527      }
3528      osi_free(p_msg);
3529      osi_free_and_reset((void **)&avrc_cmd.set_app_val.p_vals);
3530 #else
3531     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3532 #endif
3533     return status;
3534 }
3535
3536 /***************************************************************************
3537 **
3538 ** Function         get_player_app_setting_attr_text_cmd
3539 **
3540 ** Description      Get text description for app attribute
3541 **
3542 ** Returns          void
3543 **
3544 ***************************************************************************/
3545 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs)
3546 {
3547     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3548     rc_transaction_t *p_transaction = NULL;
3549     int count  = 0;
3550 #if (AVRC_CTLR_INCLUDED == TRUE)
3551     tAVRC_COMMAND avrc_cmd = {0};
3552     BT_HDR *p_msg = NULL;
3553     bt_status_t tran_status;
3554     CHECK_RC_CONNECTED
3555
3556     BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs);
3557
3558     tran_status = get_transaction(&p_transaction);
3559     if (BT_STATUS_SUCCESS != tran_status)
3560         return BT_STATUS_FAIL;
3561
3562     avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3563     avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3564     avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3565
3566     for (count = 0; count < num_attrs; count++)
3567     {
3568         avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3569     }
3570     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3571     if (status == AVRC_STS_NO_ERROR)
3572     {
3573         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3574                 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3575                 __FUNCTION__, p_transaction->lbl);
3576         BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3577                 AVRC_CMD_STATUS, data_start, p_msg->len);
3578         osi_free(p_msg);
3579         status =  BT_STATUS_SUCCESS;
3580         start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction);
3581     }
3582     else
3583     {
3584         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3585     }
3586     osi_free(p_msg);
3587 #else
3588     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3589 #endif
3590     return status;
3591 }
3592
3593 /***************************************************************************
3594 **
3595 ** Function         get_player_app_setting_val_text_cmd
3596 **
3597 ** Description      Get text description for app attribute values
3598 **
3599 ** Returns          void
3600 **
3601 ***************************************************************************/
3602 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals)
3603 {
3604     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3605     rc_transaction_t *p_transaction = NULL;
3606     int count  = 0;
3607 #if (AVRC_CTLR_INCLUDED == TRUE)
3608     tAVRC_COMMAND avrc_cmd = {0};
3609     BT_HDR *p_msg = NULL;
3610     bt_status_t tran_status;
3611     CHECK_RC_CONNECTED
3612
3613     BTIF_TRACE_DEBUG("%s: num_vals %d", __FUNCTION__, num_vals);
3614
3615     tran_status = get_transaction(&p_transaction);
3616     if (BT_STATUS_SUCCESS != tran_status)
3617         return BT_STATUS_FAIL;
3618
3619     avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3620     avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3621     avrc_cmd.get_app_val_txt.num_val = num_vals;
3622
3623     for (count = 0; count < num_vals; count++)
3624     {
3625         avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3626     }
3627     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3628     if (status == AVRC_STS_NO_ERROR)
3629     {
3630         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3631         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3632                          __FUNCTION__, p_transaction->lbl);
3633         if (p_msg != NULL)
3634         {
3635             BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3636                     AVRC_CMD_STATUS, data_start, p_msg->len);
3637             status =  BT_STATUS_SUCCESS;
3638             start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction);
3639         }
3640     }
3641     else
3642     {
3643         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3644                 __FUNCTION__, status);
3645     }
3646     osi_free(p_msg);
3647 #else
3648     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3649 #endif
3650     return status;
3651 }
3652
3653 /***************************************************************************
3654 **
3655 ** Function         register_notification_cmd
3656 **
3657 ** Description      Send Command to register for a Notification ID
3658 **
3659 ** Returns          void
3660 **
3661 ***************************************************************************/
3662 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value)
3663 {
3664
3665     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3666 #if (AVRC_CTLR_INCLUDED == TRUE)
3667     tAVRC_COMMAND avrc_cmd = {0};
3668     BT_HDR *p_msg = NULL;
3669     CHECK_RC_CONNECTED
3670
3671
3672     BTIF_TRACE_DEBUG("%s: event_id %d  event_value", __FUNCTION__, event_id, event_value);
3673
3674     avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3675     avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3676     avrc_cmd.reg_notif.event_id = event_id;
3677     avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3678     avrc_cmd.reg_notif.param = event_value;
3679     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3680     if (status == AVRC_STS_NO_ERROR)
3681     {
3682         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3683         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3684                 __FUNCTION__, label);
3685         if (p_msg != NULL)
3686         {
3687             BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF,
3688                     data_start, p_msg->len);
3689             status =  BT_STATUS_SUCCESS;
3690         }
3691     }
3692     else
3693     {
3694          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3695                             __FUNCTION__, status);
3696     }
3697     osi_free(p_msg);
3698 #else
3699     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3700 #endif
3701     return status;
3702 }
3703
3704 /***************************************************************************
3705 **
3706 ** Function         get_element_attribute_cmd
3707 **
3708 ** Description      Get Element Attribute for  attributeIds
3709 **
3710 ** Returns          void
3711 **
3712 ***************************************************************************/
3713 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
3714 {
3715     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3716     rc_transaction_t *p_transaction=NULL;
3717     int count  = 0;
3718 #if (AVRC_CTLR_INCLUDED == TRUE)
3719     tAVRC_COMMAND avrc_cmd = {0};
3720     BT_HDR *p_msg = NULL;
3721     bt_status_t tran_status;
3722     CHECK_RC_CONNECTED
3723
3724     BTIF_TRACE_DEBUG("%s: num_attribute  %d attribute_id %d",
3725                    __FUNCTION__, num_attribute, p_attr_ids[0]);
3726
3727     tran_status = get_transaction(&p_transaction);
3728     if (BT_STATUS_SUCCESS != tran_status)
3729         return BT_STATUS_FAIL;
3730
3731     avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3732     avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3733     avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3734     avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3735     for (count = 0; count < num_attribute; count++)
3736     {
3737         avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3738     }
3739
3740     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3741     if (status == AVRC_STS_NO_ERROR)
3742     {
3743         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3744         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3745                 __FUNCTION__, p_transaction->lbl);
3746         if (p_msg != NULL)
3747         {
3748             BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3749                     AVRC_CMD_STATUS, data_start, p_msg->len);
3750             status =  BT_STATUS_SUCCESS;
3751             start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR,
3752                     p_transaction);
3753         }
3754     }
3755     else
3756     {
3757          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3758                             __FUNCTION__, status);
3759     }
3760     osi_free(p_msg);
3761 #else
3762     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3763 #endif
3764     return status;
3765 }
3766
3767 /***************************************************************************
3768 **
3769 ** Function         get_play_status_cmd
3770 **
3771 ** Description      Get Element Attribute for  attributeIds
3772 **
3773 ** Returns          void
3774 **
3775 ***************************************************************************/
3776 static bt_status_t get_play_status_cmd(void)
3777 {
3778     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3779     rc_transaction_t *p_transaction = NULL;
3780 #if (AVRC_CTLR_INCLUDED == TRUE)
3781     tAVRC_COMMAND avrc_cmd = {0};
3782     BT_HDR *p_msg = NULL;
3783     bt_status_t tran_status;
3784     CHECK_RC_CONNECTED
3785
3786     BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3787     tran_status = get_transaction(&p_transaction);
3788     if (BT_STATUS_SUCCESS != tran_status)
3789         return BT_STATUS_FAIL;
3790
3791     avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3792     avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3793     avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3794     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3795     if (status == AVRC_STS_NO_ERROR)
3796     {
3797         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3798         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3799                 __FUNCTION__, p_transaction->lbl);
3800         if (p_msg != NULL)
3801         {
3802             BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,
3803                     AVRC_CMD_STATUS, data_start, p_msg->len);
3804             status =  BT_STATUS_SUCCESS;
3805             start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction);
3806         }
3807     }
3808     else
3809     {
3810          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3811                             __FUNCTION__, status);
3812     }
3813     osi_free(p_msg);
3814 #else
3815     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3816 #endif
3817     return status;
3818
3819 }
3820
3821 /***************************************************************************
3822 **
3823 ** Function         set_volume_rsp
3824 **
3825 ** Description      Rsp for SetAbsoluteVolume Command
3826 **
3827 ** Returns          void
3828 **
3829 ***************************************************************************/
3830 static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label)
3831 {
3832     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3833 #if (AVRC_CTLR_INCLUDED == TRUE)
3834     tAVRC_RESPONSE avrc_rsp;
3835     BT_HDR *p_msg = NULL;
3836     CHECK_RC_CONNECTED
3837
3838     BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol);
3839
3840     avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3841     avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3842     avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3843     avrc_rsp.volume.volume = abs_vol;
3844     status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3845     if (status == AVRC_STS_NO_ERROR)
3846     {
3847         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3848         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3849                 __FUNCTION__, btif_rc_cb.rc_vol_label);
3850         if (p_msg != NULL)
3851         {
3852             BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3853                     BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0);
3854             status =  BT_STATUS_SUCCESS;
3855         }
3856     }
3857     else
3858     {
3859          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3860                             __FUNCTION__, status);
3861     }
3862     osi_free(p_msg);
3863 #else
3864     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3865 #endif
3866     return status;
3867 }
3868
3869 /***************************************************************************
3870 **
3871 ** Function         send_register_abs_vol_rsp
3872 **
3873 ** Description      Rsp for Notification of Absolute Volume
3874 **
3875 ** Returns          void
3876 **
3877 ***************************************************************************/
3878 static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type,
3879             uint8_t abs_vol, uint8_t label)
3880 {
3881     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3882     tAVRC_RESPONSE avrc_rsp;
3883     BT_HDR *p_msg = NULL;
3884 #if (AVRC_CTLR_INCLUDED == TRUE)
3885     BTIF_TRACE_DEBUG("%s: rsp_type  %d abs_vol %d", __func__, rsp_type, abs_vol);
3886     CHECK_RC_CONNECTED
3887
3888     avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3889     avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3890     avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3891     avrc_rsp.reg_notif.param.volume = abs_vol;
3892     avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3893
3894     status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3895     if (status == AVRC_STS_NO_ERROR) {
3896         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3897                          __func__, label);
3898         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3899         BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3900                         (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ?
3901                             AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3902                         data_start, p_msg->len, 0);
3903         status = BT_STATUS_SUCCESS;
3904     } else {
3905         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3906                          __func__, status);
3907     }
3908     osi_free(p_msg);
3909
3910 #else
3911     BTIF_TRACE_DEBUG("%s: feature not enabled", __func__);
3912 #endif
3913     return status;
3914 }
3915
3916 /***************************************************************************
3917 **
3918 ** Function         send_groupnavigation_cmd
3919 **
3920 ** Description      Send Pass-Through command
3921 **
3922 ** Returns          void
3923 **
3924 ***************************************************************************/
3925 static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code,
3926                                             uint8_t key_state)
3927 {
3928     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3929 #if (AVRC_CTLR_INCLUDED == TRUE)
3930     rc_transaction_t *p_transaction=NULL;
3931     BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3932                                                     key_code, key_state);
3933     CHECK_RC_CONNECTED
3934     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3935     {
3936         bt_status_t tran_status = get_transaction(&p_transaction);
3937         if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3938              UINT8 buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3939              UINT8* start = buffer;
3940              UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3941              *(start)++ = 0;
3942              UINT8_TO_BE_STREAM(start, key_code);
3943              BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle,
3944                                          p_transaction->lbl,
3945                                          (tBTA_AV_STATE)key_state, buffer,
3946                                          AVRC_PASS_THRU_GROUP_LEN);
3947              status =  BT_STATUS_SUCCESS;
3948              BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
3949                               __FUNCTION__);
3950         }
3951         else
3952         {
3953             status =  BT_STATUS_FAIL;
3954             BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
3955         }
3956     }
3957     else
3958     {
3959         status =  BT_STATUS_FAIL;
3960         BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
3961     }
3962 #else
3963     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3964 #endif
3965     return status;
3966 }
3967
3968 /***************************************************************************
3969 **
3970 ** Function         send_passthrough_cmd
3971 **
3972 ** Description      Send Pass-Through command
3973 **
3974 ** Returns          void
3975 **
3976 ***************************************************************************/
3977 static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
3978 {
3979     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3980 #if (AVRC_CTLR_INCLUDED == TRUE)
3981     CHECK_RC_CONNECTED
3982     rc_transaction_t *p_transaction=NULL;
3983     BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3984                                                     key_code, key_state);
3985     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3986     {
3987         bt_status_t tran_status = get_transaction(&p_transaction);
3988         if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
3989         {
3990             BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3991                 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
3992             status =  BT_STATUS_SUCCESS;
3993             BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
3994         }
3995         else
3996         {
3997             status =  BT_STATUS_FAIL;
3998             BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
3999         }
4000     }
4001     else
4002     {
4003         status =  BT_STATUS_FAIL;
4004         BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
4005     }
4006 #else
4007     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
4008 #endif
4009     return status;
4010 }
4011
4012 static const btrc_interface_t bt_rc_interface = {
4013     sizeof(bt_rc_interface),
4014     init,
4015     get_play_status_rsp,
4016     NULL, /* list_player_app_attr_rsp */
4017     NULL, /* list_player_app_value_rsp */
4018     NULL, /* get_player_app_value_rsp */
4019     NULL, /* get_player_app_attr_text_rsp */
4020     NULL, /* get_player_app_value_text_rsp */
4021     get_element_attr_rsp,
4022     NULL, /* set_player_app_value_rsp */
4023     register_notification_rsp,
4024     set_volume,
4025     cleanup,
4026 };
4027
4028 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
4029     sizeof(bt_rc_ctrl_interface),
4030     init_ctrl,
4031     send_passthrough_cmd,
4032     send_groupnavigation_cmd,
4033     change_player_app_setting,
4034     set_volume_rsp,
4035     volume_change_notification_rsp,
4036     cleanup_ctrl,
4037 };
4038
4039 /*******************************************************************************
4040 **
4041 ** Function         btif_rc_get_interface
4042 **
4043 ** Description      Get the AVRCP Target callback interface
4044 **
4045 ** Returns          btav_interface_t
4046 **
4047 *******************************************************************************/
4048 const btrc_interface_t *btif_rc_get_interface(void)
4049 {
4050     BTIF_TRACE_EVENT("%s", __FUNCTION__);
4051     return &bt_rc_interface;
4052 }
4053
4054 /*******************************************************************************
4055 **
4056 ** Function         btif_rc_ctrl_get_interface
4057 **
4058 ** Description      Get the AVRCP Controller callback interface
4059 **
4060 ** Returns          btav_interface_t
4061 **
4062 *******************************************************************************/
4063 const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
4064 {
4065     BTIF_TRACE_EVENT("%s", __FUNCTION__);
4066     return &bt_rc_ctrl_interface;
4067 }
4068
4069 /*******************************************************************************
4070 **      Function         initialize_transaction
4071 **
4072 **      Description    Initializes fields of the transaction structure
4073 **
4074 **      Returns          void
4075 *******************************************************************************/
4076 static void initialize_transaction(int lbl)
4077 {
4078     pthread_mutex_lock(&device.lbllock);
4079     if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
4080         if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
4081             clear_cmd_timeout(lbl);
4082         }
4083         device.transaction[lbl].lbl = lbl;
4084         device.transaction[lbl].in_use=FALSE;
4085         device.transaction[lbl].handle=0;
4086     }
4087     pthread_mutex_unlock(&device.lbllock);
4088 }
4089
4090 /*******************************************************************************
4091 **      Function         lbl_init
4092 **
4093 **      Description    Initializes label structures and mutexes.
4094 **
4095 **      Returns         void
4096 *******************************************************************************/
4097 void lbl_init()
4098 {
4099     memset(&device,0,sizeof(rc_device_t));
4100     pthread_mutexattr_t attr;
4101     pthread_mutexattr_init(&attr);
4102     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
4103     pthread_mutex_init(&(device.lbllock), &attr);
4104     pthread_mutexattr_destroy(&attr);
4105     init_all_transactions();
4106 }
4107
4108 /*******************************************************************************
4109 **
4110 ** Function         init_all_transactions
4111 **
4112 ** Description    Initializes all transactions
4113 **
4114 ** Returns          void
4115 *******************************************************************************/
4116 void init_all_transactions()
4117 {
4118     UINT8 txn_indx=0;
4119     for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
4120     {
4121         initialize_transaction(txn_indx);
4122     }
4123 }
4124
4125 /*******************************************************************************
4126 **
4127 ** Function         get_transaction_by_lbl
4128 **
4129 ** Description    Will return a transaction based on the label. If not inuse
4130 **                     will return an error.
4131 **
4132 ** Returns          bt_status_t
4133 *******************************************************************************/
4134 rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
4135 {
4136     rc_transaction_t *transaction = NULL;
4137     pthread_mutex_lock(&device.lbllock);
4138
4139     /* Determine if this is a valid label */
4140     if (lbl < MAX_TRANSACTIONS_PER_SESSION)
4141     {
4142         if (FALSE==device.transaction[lbl].in_use)
4143         {
4144             transaction = NULL;
4145         }
4146         else
4147         {
4148             transaction = &(device.transaction[lbl]);
4149             BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
4150         }
4151     }
4152
4153     pthread_mutex_unlock(&device.lbllock);
4154     return transaction;
4155 }
4156
4157 /*******************************************************************************
4158 **
4159 ** Function         get_transaction
4160 **
4161 ** Description    Obtains the transaction details.
4162 **
4163 ** Returns          bt_status_t
4164 *******************************************************************************/
4165
4166 bt_status_t  get_transaction(rc_transaction_t **ptransaction)
4167 {
4168     bt_status_t result = BT_STATUS_NOMEM;
4169     UINT8 i=0;
4170     pthread_mutex_lock(&device.lbllock);
4171
4172     // Check for unused transactions
4173     for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
4174     {
4175         if (FALSE==device.transaction[i].in_use)
4176         {
4177             BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
4178             device.transaction[i].in_use = TRUE;
4179             *ptransaction = &(device.transaction[i]);
4180             result = BT_STATUS_SUCCESS;
4181             break;
4182         }
4183     }
4184
4185     pthread_mutex_unlock(&device.lbllock);
4186     return result;
4187 }
4188
4189 /*******************************************************************************
4190 **
4191 ** Function         release_transaction
4192 **
4193 ** Description    Will release a transaction for reuse
4194 **
4195 ** Returns          bt_status_t
4196 *******************************************************************************/
4197 void release_transaction(UINT8 lbl)
4198 {
4199     rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
4200
4201     /* If the transaction is in use... */
4202     if (transaction != NULL)
4203     {
4204         BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
4205         initialize_transaction(lbl);
4206     }
4207 }
4208
4209 /*******************************************************************************
4210 **
4211 ** Function         lbl_destroy
4212 **
4213 ** Description    Cleanup of the mutex
4214 **
4215 ** Returns          void
4216 *******************************************************************************/
4217 void lbl_destroy()
4218 {
4219     pthread_mutex_destroy(&(device.lbllock));
4220 }
4221
4222 /*******************************************************************************
4223 **      Function       sleep_ms
4224 **
4225 **      Description    Sleep the calling thread unconditionally for
4226 **                     |timeout_ms| milliseconds.
4227 **
4228 **      Returns        void
4229 *******************************************************************************/
4230 static void sleep_ms(period_ms_t timeout_ms) {
4231     struct timespec delay;
4232     delay.tv_sec = timeout_ms / 1000;
4233     delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000);
4234
4235     int err;
4236     do {
4237         err = nanosleep(&delay, &delay);
4238     } while (err == -1 && errno == EINTR);
4239 }
4240
4241 static bool absolute_volume_disabled() {
4242     char volume_disabled[PROPERTY_VALUE_MAX] = {0};
4243     osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
4244     if (strncmp(volume_disabled, "true", 4) == 0) {
4245         BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__);
4246         return true;
4247     }
4248     return false;
4249 }