OSDN Git Service

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