OSDN Git Service

Removed checks for NULL returns after osi_calloc() / osi_malloc()
[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,
3007                                            tAVRC_GET_ELEM_ATTRS_RSP *p_rsp)
3008 {
3009     if (p_rsp->status == AVRC_STS_NO_ERROR) {
3010         bt_bdaddr_t rc_addr;
3011         size_t buf_size = p_rsp->num_attr * sizeof(btrc_element_attr_val_t);
3012         btrc_element_attr_val_t *p_attr =
3013             (btrc_element_attr_val_t *)osi_calloc(buf_size);
3014
3015         bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3016
3017         for (int i = 0; i < p_rsp->num_attr; i++) {
3018             p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
3019             /* Todo. Legth limit check to include null */
3020             if (p_rsp->p_attrs[i].name.str_len &&
3021                 p_rsp->p_attrs[i].name.p_str) {
3022                 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str,
3023                        p_rsp->p_attrs[i].name.str_len);
3024                 osi_free_and_reset((void **)&p_rsp->p_attrs[i].name.p_str);
3025             }
3026         }
3027         HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb,
3028                   &rc_addr, p_rsp->num_attr, p_attr);
3029         osi_free(p_attr);
3030     } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
3031         /* Retry for timeout case, this covers error handling
3032          * for continuation failure also.
3033          */
3034         UINT32 attr_list[] = {
3035             AVRC_MEDIA_ATTR_ID_TITLE,
3036             AVRC_MEDIA_ATTR_ID_ARTIST,
3037             AVRC_MEDIA_ATTR_ID_ALBUM,
3038             AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3039             AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
3040             AVRC_MEDIA_ATTR_ID_GENRE,
3041             AVRC_MEDIA_ATTR_ID_PLAYING_TIME
3042             };
3043         get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
3044     } else {
3045         BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d",
3046                          __func__, p_rsp->status);
3047     }
3048 }
3049
3050 /***************************************************************************
3051 **
3052 ** Function         handle_get_playstatus_response
3053 **
3054 ** Description      handles the the play status response, calls
3055 **                  HAL callback to update play position.
3056 ** Returns          None
3057 **
3058 ***************************************************************************/
3059 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp)
3060 {
3061     bt_bdaddr_t rc_addr;
3062
3063     bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3064
3065     if (p_rsp->status == AVRC_STS_NO_ERROR)
3066     {
3067         HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb,
3068             &rc_addr, p_rsp->song_len, p_rsp->song_pos);
3069     }
3070     else
3071     {
3072         BTIF_TRACE_ERROR("%s: Error in get play status procedure %d",
3073             __FUNCTION__, p_rsp->status);
3074     }
3075 }
3076
3077 /***************************************************************************
3078 **
3079 ** Function         clear_cmd_timeout
3080 **
3081 ** Description      helper function to stop the command timeout timer
3082 ** Returns          None
3083 **
3084 ***************************************************************************/
3085 static void clear_cmd_timeout (UINT8 label)
3086 {
3087     rc_transaction_t *p_txn;
3088
3089     p_txn = get_transaction_by_lbl (label);
3090     if (p_txn == NULL)
3091     {
3092         BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__);
3093         return;
3094     }
3095
3096     if (p_txn->txn_timer != NULL)
3097         alarm_cancel(p_txn->txn_timer);
3098 }
3099
3100 /***************************************************************************
3101 **
3102 ** Function         handle_avk_rc_metamsg_rsp
3103 **
3104 ** Description      Handle RC metamessage response
3105 **
3106 ** Returns          void
3107 **
3108 ***************************************************************************/
3109 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
3110 {
3111     tAVRC_RESPONSE    avrc_response = {0};
3112     UINT8             scratch_buf[512] = {0};// this variable is unused
3113     UINT16            buf_len;
3114     tAVRC_STS         status;
3115
3116     BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ", __FUNCTION__,
3117                         pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
3118
3119     if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&&
3120                 (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&&
3121                 (pmeta_msg->code <= AVRC_RSP_INTERIM))
3122     {
3123         status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
3124         BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d",
3125                          __FUNCTION__, status, avrc_response.pdu,
3126                          pmeta_msg->p_msg->vendor.hdr.ctype);
3127
3128         switch (avrc_response.pdu)
3129         {
3130             case AVRC_PDU_REGISTER_NOTIFICATION:
3131                 handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
3132                 if (pmeta_msg->code == AVRC_RSP_INTERIM)
3133                 {
3134                     /* Don't free the transaction Id */
3135                     clear_cmd_timeout (pmeta_msg->label);
3136                     return;
3137                 }
3138                 break;
3139
3140             case AVRC_PDU_GET_CAPABILITIES:
3141                 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
3142                 break;
3143
3144             case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3145                 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
3146                 break;
3147
3148             case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3149                 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
3150                 break;
3151
3152             case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3153                 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
3154                 break;
3155
3156             case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3157                 handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
3158                 break;
3159
3160             case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3161                 handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
3162                 break;
3163
3164             case AVRC_PDU_SET_PLAYER_APP_VALUE:
3165                 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
3166                 break;
3167
3168             case AVRC_PDU_GET_ELEMENT_ATTR:
3169                 handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs);
3170                 break;
3171
3172             case AVRC_PDU_GET_PLAY_STATUS:
3173                 handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
3174                 break;
3175         }
3176         release_transaction(pmeta_msg->label);
3177     }
3178     else
3179     {
3180         BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3181             __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3182         return;
3183     }
3184 }
3185
3186 /***************************************************************************
3187 **
3188 ** Function         handle_avk_rc_metamsg_cmd
3189 **
3190 ** Description      Handle RC metamessage response
3191 **
3192 ** Returns          void
3193 **
3194 ***************************************************************************/
3195 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg)
3196 {
3197     tAVRC_COMMAND    avrc_cmd = {0};
3198     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3199     BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d  ",__FUNCTION__,
3200                      pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code);
3201     if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&&
3202                 (pmeta_msg->code <= AVRC_CMD_GEN_INQ))
3203     {
3204         status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
3205         BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
3206                          __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
3207
3208         if (status != AVRC_STS_NO_ERROR)
3209         {
3210             /* return error */
3211             BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
3212                 __FUNCTION__, status);
3213             send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status);
3214         }
3215         else
3216         {
3217             if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
3218             {
3219                 UINT8 event_id = avrc_cmd.reg_notif.event_id;
3220                 BTIF_TRACE_EVENT("%s:Register notification event_id: %s",
3221                         __FUNCTION__, dump_rc_notification_event_id(event_id));
3222             }
3223             else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME)
3224             {
3225                 BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__);
3226             }
3227             btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label);
3228         }
3229     }
3230     else
3231     {
3232       BTIF_TRACE_DEBUG("%s:Invalid Vendor Command  code: %d len: %d. Not processing it.",
3233                        __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3234         return;
3235     }
3236 }
3237 #endif
3238
3239 /***************************************************************************
3240 **
3241 ** Function         cleanup
3242 **
3243 ** Description      Closes the AVRC interface
3244 **
3245 ** Returns          void
3246 **
3247 ***************************************************************************/
3248 static void cleanup()
3249 {
3250     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3251     close_uinput();
3252     if (bt_rc_callbacks)
3253     {
3254         bt_rc_callbacks = NULL;
3255     }
3256     alarm_free(btif_rc_cb.rc_play_status_timer);
3257     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3258     lbl_destroy();
3259     BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3260 }
3261
3262 /***************************************************************************
3263 **
3264 ** Function         cleanup_ctrl
3265 **
3266 ** Description      Closes the AVRC Controller interface
3267 **
3268 ** Returns          void
3269 **
3270 ***************************************************************************/
3271 static void cleanup_ctrl()
3272 {
3273     BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3274
3275     if (bt_rc_ctrl_callbacks)
3276     {
3277         bt_rc_ctrl_callbacks = NULL;
3278     }
3279     alarm_free(btif_rc_cb.rc_play_status_timer);
3280     memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3281     lbl_destroy();
3282     BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3283 }
3284
3285 /***************************************************************************
3286 **
3287 ** Function         getcapabilities_cmd
3288 **
3289 ** Description      GetCapabilties from Remote(Company_ID, Events_Supported)
3290 **
3291 ** Returns          void
3292 **
3293 ***************************************************************************/
3294 static bt_status_t getcapabilities_cmd (uint8_t cap_id)
3295 {
3296     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3297     rc_transaction_t *p_transaction = NULL;
3298 #if (AVRC_CTLR_INCLUDED == TRUE)
3299     BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id);
3300     CHECK_RC_CONNECTED
3301     bt_status_t tran_status=get_transaction(&p_transaction);
3302     if (BT_STATUS_SUCCESS != tran_status)
3303         return BT_STATUS_FAIL;
3304
3305      tAVRC_COMMAND avrc_cmd = {0};
3306      BT_HDR *p_msg = NULL;
3307      avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
3308      avrc_cmd.get_caps.capability_id = cap_id;
3309      avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
3310      avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
3311      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3312      if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3313      {
3314          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3315          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3316                             __FUNCTION__,p_transaction->lbl);
3317          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3318                                                           data_start, p_msg->len);
3319          status =  BT_STATUS_SUCCESS;
3320          start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction);
3321      }
3322      else
3323      {
3324          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3325                              __FUNCTION__, status);
3326      }
3327      osi_free(p_msg);
3328 #else
3329     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3330 #endif
3331     return status;
3332 }
3333
3334 /***************************************************************************
3335 **
3336 ** Function         list_player_app_setting_attrib_cmd
3337 **
3338 ** Description      Get supported List Player Attributes
3339 **
3340 ** Returns          void
3341 **
3342 ***************************************************************************/
3343 static bt_status_t list_player_app_setting_attrib_cmd(void)
3344 {
3345     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3346     rc_transaction_t *p_transaction = NULL;
3347 #if (AVRC_CTLR_INCLUDED == TRUE)
3348     BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3349     CHECK_RC_CONNECTED
3350     bt_status_t tran_status=get_transaction(&p_transaction);
3351     if (BT_STATUS_SUCCESS != tran_status)
3352         return BT_STATUS_FAIL;
3353
3354      tAVRC_COMMAND avrc_cmd = {0};
3355      BT_HDR *p_msg = NULL;
3356      avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
3357      avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
3358      avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
3359      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3360      if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3361      {
3362          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3363          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3364                             __FUNCTION__,p_transaction->lbl);
3365          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3366                                                           data_start, p_msg->len);
3367          status =  BT_STATUS_SUCCESS;
3368          start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction);
3369      }
3370      else
3371      {
3372
3373          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3374                             __FUNCTION__, status);
3375      }
3376      osi_free(p_msg);
3377 #else
3378     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3379 #endif
3380     return status;
3381 }
3382
3383 /***************************************************************************
3384 **
3385 ** Function         list_player_app_setting_value_cmd
3386 **
3387 ** Description      Get values of supported Player Attributes
3388 **
3389 ** Returns          void
3390 **
3391 ***************************************************************************/
3392 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id)
3393 {
3394     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3395     rc_transaction_t *p_transaction=NULL;
3396 #if (AVRC_CTLR_INCLUDED == TRUE)
3397     BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id);
3398     CHECK_RC_CONNECTED
3399     bt_status_t tran_status=get_transaction(&p_transaction);
3400     if (BT_STATUS_SUCCESS != tran_status)
3401         return BT_STATUS_FAIL;
3402
3403      tAVRC_COMMAND avrc_cmd = {0};
3404      BT_HDR *p_msg = NULL;
3405      avrc_cmd.list_app_values.attr_id = attrib_id;
3406      avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
3407      avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
3408      avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
3409      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3410      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3411      {
3412          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3413          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3414                             __FUNCTION__,p_transaction->lbl);
3415          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3416                                data_start, p_msg->len);
3417          status =  BT_STATUS_SUCCESS;
3418          start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction);
3419      }
3420      else
3421      {
3422          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3423      }
3424      osi_free(p_msg);
3425 #else
3426     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3427 #endif
3428     return status;
3429 }
3430
3431 /***************************************************************************
3432 **
3433 ** Function         get_player_app_setting_cmd
3434 **
3435 ** Description      Get current values of Player Attributes
3436 **
3437 ** Returns          void
3438 **
3439 ***************************************************************************/
3440 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids)
3441 {
3442     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3443     rc_transaction_t *p_transaction = NULL;
3444     int count  = 0;
3445 #if (AVRC_CTLR_INCLUDED == TRUE)
3446     BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3447     CHECK_RC_CONNECTED
3448     bt_status_t tran_status=get_transaction(&p_transaction);
3449     if (BT_STATUS_SUCCESS != tran_status)
3450         return BT_STATUS_FAIL;
3451
3452      tAVRC_COMMAND avrc_cmd = {0};
3453      BT_HDR *p_msg = NULL;
3454      avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
3455      avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
3456      avrc_cmd.get_cur_app_val.num_attr = num_attrib;
3457      avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
3458
3459      for (count = 0; count < num_attrib; count++)
3460      {
3461          avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
3462      }
3463      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3464      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3465      {
3466          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3467          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3468                             __FUNCTION__,p_transaction->lbl);
3469          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3470                           data_start, p_msg->len);
3471          status =  BT_STATUS_SUCCESS;
3472          start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction);
3473      }
3474      else
3475      {
3476          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3477                             __FUNCTION__, status);
3478      }
3479      osi_free(p_msg);
3480 #else
3481     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3482 #endif
3483     return status;
3484 }
3485
3486 /***************************************************************************
3487 **
3488 ** Function         change_player_app_setting
3489 **
3490 ** Description      Set current values of Player Attributes
3491 **
3492 ** Returns          void
3493 **
3494 ***************************************************************************/
3495 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)
3496 {
3497     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3498     rc_transaction_t *p_transaction = NULL;
3499     int count  = 0;
3500 #if (AVRC_CTLR_INCLUDED == TRUE)
3501     BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3502     CHECK_RC_CONNECTED
3503     bt_status_t tran_status=get_transaction(&p_transaction);
3504     if (BT_STATUS_SUCCESS != tran_status)
3505         return BT_STATUS_FAIL;
3506
3507      tAVRC_COMMAND avrc_cmd = {0};
3508      BT_HDR *p_msg = NULL;
3509      avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
3510      avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
3511      avrc_cmd.set_app_val.num_val = num_attrib;
3512      avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
3513      avrc_cmd.set_app_val.p_vals =
3514            (tAVRC_APP_SETTING *)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
3515      for (count = 0; count < num_attrib; count++)
3516      {
3517          avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
3518          avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
3519      }
3520      status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3521      if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3522      {
3523          UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3524          BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3525                             __FUNCTION__,p_transaction->lbl);
3526          BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_CTRL,
3527                               data_start, p_msg->len);
3528          status =  BT_STATUS_SUCCESS;
3529          start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction);
3530      }
3531      else
3532      {
3533          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3534                             __FUNCTION__, status);
3535      }
3536      osi_free(p_msg);
3537      osi_free_and_reset((void **)&avrc_cmd.set_app_val.p_vals);
3538 #else
3539     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3540 #endif
3541     return status;
3542 }
3543
3544 /***************************************************************************
3545 **
3546 ** Function         get_player_app_setting_attr_text_cmd
3547 **
3548 ** Description      Get text description for app attribute
3549 **
3550 ** Returns          void
3551 **
3552 ***************************************************************************/
3553 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs)
3554 {
3555     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3556     rc_transaction_t *p_transaction = NULL;
3557     int count  = 0;
3558 #if (AVRC_CTLR_INCLUDED == TRUE)
3559     tAVRC_COMMAND avrc_cmd = {0};
3560     BT_HDR *p_msg = NULL;
3561     bt_status_t tran_status;
3562     CHECK_RC_CONNECTED
3563
3564     BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs);
3565
3566     tran_status = get_transaction(&p_transaction);
3567     if (BT_STATUS_SUCCESS != tran_status)
3568         return BT_STATUS_FAIL;
3569
3570     avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3571     avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3572     avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3573
3574     for (count = 0; count < num_attrs; count++)
3575     {
3576         avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3577     }
3578     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3579     if (status == AVRC_STS_NO_ERROR)
3580     {
3581         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3582                 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3583                 __FUNCTION__, p_transaction->lbl);
3584         BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3585                 AVRC_CMD_STATUS, data_start, p_msg->len);
3586         osi_free(p_msg);
3587         status =  BT_STATUS_SUCCESS;
3588         start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction);
3589     }
3590     else
3591     {
3592         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3593     }
3594     osi_free(p_msg);
3595 #else
3596     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3597 #endif
3598     return status;
3599 }
3600
3601 /***************************************************************************
3602 **
3603 ** Function         get_player_app_setting_val_text_cmd
3604 **
3605 ** Description      Get text description for app attribute values
3606 **
3607 ** Returns          void
3608 **
3609 ***************************************************************************/
3610 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals)
3611 {
3612     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3613     rc_transaction_t *p_transaction = NULL;
3614     int count  = 0;
3615 #if (AVRC_CTLR_INCLUDED == TRUE)
3616     tAVRC_COMMAND avrc_cmd = {0};
3617     BT_HDR *p_msg = NULL;
3618     bt_status_t tran_status;
3619     CHECK_RC_CONNECTED
3620
3621     BTIF_TRACE_DEBUG("%s: num_vals %d", __FUNCTION__, num_vals);
3622
3623     tran_status = get_transaction(&p_transaction);
3624     if (BT_STATUS_SUCCESS != tran_status)
3625         return BT_STATUS_FAIL;
3626
3627     avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3628     avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3629     avrc_cmd.get_app_val_txt.num_val = num_vals;
3630
3631     for (count = 0; count < num_vals; count++)
3632     {
3633         avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3634     }
3635     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3636     if (status == AVRC_STS_NO_ERROR)
3637     {
3638         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3639         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3640                          __FUNCTION__, p_transaction->lbl);
3641         if (p_msg != NULL)
3642         {
3643             BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3644                     AVRC_CMD_STATUS, data_start, p_msg->len);
3645             status =  BT_STATUS_SUCCESS;
3646             start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction);
3647         }
3648     }
3649     else
3650     {
3651         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3652                 __FUNCTION__, status);
3653     }
3654     osi_free(p_msg);
3655 #else
3656     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3657 #endif
3658     return status;
3659 }
3660
3661 /***************************************************************************
3662 **
3663 ** Function         register_notification_cmd
3664 **
3665 ** Description      Send Command to register for a Notification ID
3666 **
3667 ** Returns          void
3668 **
3669 ***************************************************************************/
3670 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value)
3671 {
3672
3673     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3674 #if (AVRC_CTLR_INCLUDED == TRUE)
3675     tAVRC_COMMAND avrc_cmd = {0};
3676     BT_HDR *p_msg = NULL;
3677     CHECK_RC_CONNECTED
3678
3679
3680     BTIF_TRACE_DEBUG("%s: event_id %d  event_value", __FUNCTION__, event_id, event_value);
3681
3682     avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3683     avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3684     avrc_cmd.reg_notif.event_id = event_id;
3685     avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3686     avrc_cmd.reg_notif.param = event_value;
3687     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3688     if (status == AVRC_STS_NO_ERROR)
3689     {
3690         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3691         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3692                 __FUNCTION__, label);
3693         if (p_msg != NULL)
3694         {
3695             BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF,
3696                     data_start, p_msg->len);
3697             status =  BT_STATUS_SUCCESS;
3698         }
3699     }
3700     else
3701     {
3702          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3703                             __FUNCTION__, status);
3704     }
3705     osi_free(p_msg);
3706 #else
3707     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3708 #endif
3709     return status;
3710 }
3711
3712 /***************************************************************************
3713 **
3714 ** Function         get_element_attribute_cmd
3715 **
3716 ** Description      Get Element Attribute for  attributeIds
3717 **
3718 ** Returns          void
3719 **
3720 ***************************************************************************/
3721 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
3722 {
3723     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3724     rc_transaction_t *p_transaction=NULL;
3725     int count  = 0;
3726 #if (AVRC_CTLR_INCLUDED == TRUE)
3727     tAVRC_COMMAND avrc_cmd = {0};
3728     BT_HDR *p_msg = NULL;
3729     bt_status_t tran_status;
3730     CHECK_RC_CONNECTED
3731
3732     BTIF_TRACE_DEBUG("%s: num_attribute  %d attribute_id %d",
3733                    __FUNCTION__, num_attribute, p_attr_ids[0]);
3734
3735     tran_status = get_transaction(&p_transaction);
3736     if (BT_STATUS_SUCCESS != tran_status)
3737         return BT_STATUS_FAIL;
3738
3739     avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3740     avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3741     avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3742     avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3743     for (count = 0; count < num_attribute; count++)
3744     {
3745         avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3746     }
3747
3748     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3749     if (status == AVRC_STS_NO_ERROR)
3750     {
3751         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3752         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3753                 __FUNCTION__, p_transaction->lbl);
3754         if (p_msg != NULL)
3755         {
3756             BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3757                     AVRC_CMD_STATUS, data_start, p_msg->len);
3758             status =  BT_STATUS_SUCCESS;
3759             start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR,
3760                     p_transaction);
3761         }
3762     }
3763     else
3764     {
3765          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3766                             __FUNCTION__, status);
3767     }
3768     osi_free(p_msg);
3769 #else
3770     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3771 #endif
3772     return status;
3773 }
3774
3775 /***************************************************************************
3776 **
3777 ** Function         get_play_status_cmd
3778 **
3779 ** Description      Get Element Attribute for  attributeIds
3780 **
3781 ** Returns          void
3782 **
3783 ***************************************************************************/
3784 static bt_status_t get_play_status_cmd(void)
3785 {
3786     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3787     rc_transaction_t *p_transaction = NULL;
3788 #if (AVRC_CTLR_INCLUDED == TRUE)
3789     tAVRC_COMMAND avrc_cmd = {0};
3790     BT_HDR *p_msg = NULL;
3791     bt_status_t tran_status;
3792     CHECK_RC_CONNECTED
3793
3794     BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3795     tran_status = get_transaction(&p_transaction);
3796     if (BT_STATUS_SUCCESS != tran_status)
3797         return BT_STATUS_FAIL;
3798
3799     avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3800     avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3801     avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3802     status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3803     if (status == AVRC_STS_NO_ERROR)
3804     {
3805         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3806         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3807                 __FUNCTION__, p_transaction->lbl);
3808         if (p_msg != NULL)
3809         {
3810             BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,
3811                     AVRC_CMD_STATUS, data_start, p_msg->len);
3812             status =  BT_STATUS_SUCCESS;
3813             start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction);
3814         }
3815     }
3816     else
3817     {
3818          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3819                             __FUNCTION__, status);
3820     }
3821     osi_free(p_msg);
3822 #else
3823     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3824 #endif
3825     return status;
3826
3827 }
3828
3829 /***************************************************************************
3830 **
3831 ** Function         set_volume_rsp
3832 **
3833 ** Description      Rsp for SetAbsoluteVolume Command
3834 **
3835 ** Returns          void
3836 **
3837 ***************************************************************************/
3838 static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label)
3839 {
3840     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3841 #if (AVRC_CTLR_INCLUDED == TRUE)
3842     tAVRC_RESPONSE avrc_rsp;
3843     BT_HDR *p_msg = NULL;
3844     CHECK_RC_CONNECTED
3845
3846     BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol);
3847
3848     avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3849     avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3850     avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3851     avrc_rsp.volume.volume = abs_vol;
3852     status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3853     if (status == AVRC_STS_NO_ERROR)
3854     {
3855         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3856         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3857                 __FUNCTION__, btif_rc_cb.rc_vol_label);
3858         if (p_msg != NULL)
3859         {
3860             BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3861                     BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0);
3862             status =  BT_STATUS_SUCCESS;
3863         }
3864     }
3865     else
3866     {
3867          BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3868                             __FUNCTION__, status);
3869     }
3870     osi_free(p_msg);
3871 #else
3872     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3873 #endif
3874     return status;
3875 }
3876
3877 /***************************************************************************
3878 **
3879 ** Function         send_register_abs_vol_rsp
3880 **
3881 ** Description      Rsp for Notification of Absolute Volume
3882 **
3883 ** Returns          void
3884 **
3885 ***************************************************************************/
3886 static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type,
3887             uint8_t abs_vol, uint8_t label)
3888 {
3889     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3890     tAVRC_RESPONSE avrc_rsp;
3891     BT_HDR *p_msg = NULL;
3892 #if (AVRC_CTLR_INCLUDED == TRUE)
3893     BTIF_TRACE_DEBUG("%s: rsp_type  %d abs_vol %d", __func__, rsp_type, abs_vol);
3894     CHECK_RC_CONNECTED
3895
3896     avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3897     avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3898     avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3899     avrc_rsp.reg_notif.param.volume = abs_vol;
3900     avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3901
3902     status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3903     if (status == AVRC_STS_NO_ERROR) {
3904         BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3905                          __func__, label);
3906         UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3907         BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3908                         (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ?
3909                             AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3910                         data_start, p_msg->len, 0);
3911         status = BT_STATUS_SUCCESS;
3912     } else {
3913         BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3914                          __func__, status);
3915     }
3916     osi_free(p_msg);
3917
3918 #else
3919     BTIF_TRACE_DEBUG("%s: feature not enabled", __func__);
3920 #endif
3921     return status;
3922 }
3923
3924 /***************************************************************************
3925 **
3926 ** Function         send_groupnavigation_cmd
3927 **
3928 ** Description      Send Pass-Through command
3929 **
3930 ** Returns          void
3931 **
3932 ***************************************************************************/
3933 static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code,
3934                                             uint8_t key_state)
3935 {
3936     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3937 #if (AVRC_CTLR_INCLUDED == TRUE)
3938     rc_transaction_t *p_transaction=NULL;
3939     BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3940                                                     key_code, key_state);
3941     CHECK_RC_CONNECTED
3942     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3943     {
3944         bt_status_t tran_status = get_transaction(&p_transaction);
3945         if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3946              UINT8 buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3947              UINT8* start = buffer;
3948              UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3949              *(start)++ = 0;
3950              UINT8_TO_BE_STREAM(start, key_code);
3951              BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle,
3952                                          p_transaction->lbl,
3953                                          (tBTA_AV_STATE)key_state, buffer,
3954                                          AVRC_PASS_THRU_GROUP_LEN);
3955              status =  BT_STATUS_SUCCESS;
3956              BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
3957                               __FUNCTION__);
3958         }
3959         else
3960         {
3961             status =  BT_STATUS_FAIL;
3962             BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
3963         }
3964     }
3965     else
3966     {
3967         status =  BT_STATUS_FAIL;
3968         BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
3969     }
3970 #else
3971     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3972 #endif
3973     return status;
3974 }
3975
3976 /***************************************************************************
3977 **
3978 ** Function         send_passthrough_cmd
3979 **
3980 ** Description      Send Pass-Through command
3981 **
3982 ** Returns          void
3983 **
3984 ***************************************************************************/
3985 static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
3986 {
3987     tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3988 #if (AVRC_CTLR_INCLUDED == TRUE)
3989     CHECK_RC_CONNECTED
3990     rc_transaction_t *p_transaction=NULL;
3991     BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3992                                                     key_code, key_state);
3993     if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3994     {
3995         bt_status_t tran_status = get_transaction(&p_transaction);
3996         if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
3997         {
3998             BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3999                 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
4000             status =  BT_STATUS_SUCCESS;
4001             BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
4002         }
4003         else
4004         {
4005             status =  BT_STATUS_FAIL;
4006             BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
4007         }
4008     }
4009     else
4010     {
4011         status =  BT_STATUS_FAIL;
4012         BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
4013     }
4014 #else
4015     BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
4016 #endif
4017     return status;
4018 }
4019
4020 static const btrc_interface_t bt_rc_interface = {
4021     sizeof(bt_rc_interface),
4022     init,
4023     get_play_status_rsp,
4024     NULL, /* list_player_app_attr_rsp */
4025     NULL, /* list_player_app_value_rsp */
4026     NULL, /* get_player_app_value_rsp */
4027     NULL, /* get_player_app_attr_text_rsp */
4028     NULL, /* get_player_app_value_text_rsp */
4029     get_element_attr_rsp,
4030     NULL, /* set_player_app_value_rsp */
4031     register_notification_rsp,
4032     set_volume,
4033     cleanup,
4034 };
4035
4036 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
4037     sizeof(bt_rc_ctrl_interface),
4038     init_ctrl,
4039     send_passthrough_cmd,
4040     send_groupnavigation_cmd,
4041     change_player_app_setting,
4042     set_volume_rsp,
4043     volume_change_notification_rsp,
4044     cleanup_ctrl,
4045 };
4046
4047 /*******************************************************************************
4048 **
4049 ** Function         btif_rc_get_interface
4050 **
4051 ** Description      Get the AVRCP Target callback interface
4052 **
4053 ** Returns          btav_interface_t
4054 **
4055 *******************************************************************************/
4056 const btrc_interface_t *btif_rc_get_interface(void)
4057 {
4058     BTIF_TRACE_EVENT("%s", __FUNCTION__);
4059     return &bt_rc_interface;
4060 }
4061
4062 /*******************************************************************************
4063 **
4064 ** Function         btif_rc_ctrl_get_interface
4065 **
4066 ** Description      Get the AVRCP Controller callback interface
4067 **
4068 ** Returns          btav_interface_t
4069 **
4070 *******************************************************************************/
4071 const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
4072 {
4073     BTIF_TRACE_EVENT("%s", __FUNCTION__);
4074     return &bt_rc_ctrl_interface;
4075 }
4076
4077 /*******************************************************************************
4078 **      Function         initialize_transaction
4079 **
4080 **      Description    Initializes fields of the transaction structure
4081 **
4082 **      Returns          void
4083 *******************************************************************************/
4084 static void initialize_transaction(int lbl)
4085 {
4086     pthread_mutex_lock(&device.lbllock);
4087     if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
4088         if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
4089             clear_cmd_timeout(lbl);
4090         }
4091         device.transaction[lbl].lbl = lbl;
4092         device.transaction[lbl].in_use=FALSE;
4093         device.transaction[lbl].handle=0;
4094     }
4095     pthread_mutex_unlock(&device.lbllock);
4096 }
4097
4098 /*******************************************************************************
4099 **      Function         lbl_init
4100 **
4101 **      Description    Initializes label structures and mutexes.
4102 **
4103 **      Returns         void
4104 *******************************************************************************/
4105 void lbl_init()
4106 {
4107     memset(&device,0,sizeof(rc_device_t));
4108     pthread_mutexattr_t attr;
4109     pthread_mutexattr_init(&attr);
4110     pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
4111     pthread_mutex_init(&(device.lbllock), &attr);
4112     pthread_mutexattr_destroy(&attr);
4113     init_all_transactions();
4114 }
4115
4116 /*******************************************************************************
4117 **
4118 ** Function         init_all_transactions
4119 **
4120 ** Description    Initializes all transactions
4121 **
4122 ** Returns          void
4123 *******************************************************************************/
4124 void init_all_transactions()
4125 {
4126     UINT8 txn_indx=0;
4127     for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
4128     {
4129         initialize_transaction(txn_indx);
4130     }
4131 }
4132
4133 /*******************************************************************************
4134 **
4135 ** Function         get_transaction_by_lbl
4136 **
4137 ** Description    Will return a transaction based on the label. If not inuse
4138 **                     will return an error.
4139 **
4140 ** Returns          bt_status_t
4141 *******************************************************************************/
4142 rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
4143 {
4144     rc_transaction_t *transaction = NULL;
4145     pthread_mutex_lock(&device.lbllock);
4146
4147     /* Determine if this is a valid label */
4148     if (lbl < MAX_TRANSACTIONS_PER_SESSION)
4149     {
4150         if (FALSE==device.transaction[lbl].in_use)
4151         {
4152             transaction = NULL;
4153         }
4154         else
4155         {
4156             transaction = &(device.transaction[lbl]);
4157             BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
4158         }
4159     }
4160
4161     pthread_mutex_unlock(&device.lbllock);
4162     return transaction;
4163 }
4164
4165 /*******************************************************************************
4166 **
4167 ** Function         get_transaction
4168 **
4169 ** Description    Obtains the transaction details.
4170 **
4171 ** Returns          bt_status_t
4172 *******************************************************************************/
4173
4174 bt_status_t  get_transaction(rc_transaction_t **ptransaction)
4175 {
4176     bt_status_t result = BT_STATUS_NOMEM;
4177     UINT8 i=0;
4178     pthread_mutex_lock(&device.lbllock);
4179
4180     // Check for unused transactions
4181     for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
4182     {
4183         if (FALSE==device.transaction[i].in_use)
4184         {
4185             BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
4186             device.transaction[i].in_use = TRUE;
4187             *ptransaction = &(device.transaction[i]);
4188             result = BT_STATUS_SUCCESS;
4189             break;
4190         }
4191     }
4192
4193     pthread_mutex_unlock(&device.lbllock);
4194     return result;
4195 }
4196
4197 /*******************************************************************************
4198 **
4199 ** Function         release_transaction
4200 **
4201 ** Description    Will release a transaction for reuse
4202 **
4203 ** Returns          bt_status_t
4204 *******************************************************************************/
4205 void release_transaction(UINT8 lbl)
4206 {
4207     rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
4208
4209     /* If the transaction is in use... */
4210     if (transaction != NULL)
4211     {
4212         BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
4213         initialize_transaction(lbl);
4214     }
4215 }
4216
4217 /*******************************************************************************
4218 **
4219 ** Function         lbl_destroy
4220 **
4221 ** Description    Cleanup of the mutex
4222 **
4223 ** Returns          void
4224 *******************************************************************************/
4225 void lbl_destroy()
4226 {
4227     pthread_mutex_destroy(&(device.lbllock));
4228 }
4229
4230 /*******************************************************************************
4231 **      Function       sleep_ms
4232 **
4233 **      Description    Sleep the calling thread unconditionally for
4234 **                     |timeout_ms| milliseconds.
4235 **
4236 **      Returns        void
4237 *******************************************************************************/
4238 static void sleep_ms(period_ms_t timeout_ms) {
4239     struct timespec delay;
4240     delay.tv_sec = timeout_ms / 1000;
4241     delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000);
4242
4243     int err;
4244     do {
4245         err = nanosleep(&delay, &delay);
4246     } while (err == -1 && errno == EINTR);
4247 }
4248
4249 static bool absolute_volume_disabled() {
4250 #if !defined(OS_GENERIC)
4251     char volume_disabled[PROPERTY_VALUE_MAX] = {0};
4252     property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
4253     if (strncmp(volume_disabled, "true", 4) == 0) {
4254         BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__);
4255         return true;
4256     }
4257 #endif  /* !defined(OS_GENERIC) */
4258     return false;
4259 }