OSDN Git Service

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