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