OSDN Git Service

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