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