1 /*
2  * Copyright 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.cc
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 <mutex>
35 
36 #include <hardware/bluetooth.h>
37 #include <hardware/bt_rc.h>
38 
39 #include "avrc_defs.h"
40 #include "bt_common.h"
41 #include "bta_api.h"
42 #include "bta_av_api.h"
43 #include "btif_av.h"
44 #include "btif_common.h"
45 #include "btif_rc.h"
46 #include "btif_util.h"
47 #include "btu.h"
48 #include "device/include/interop.h"
49 #include "log/log.h"
50 #include "osi/include/list.h"
51 #include "osi/include/osi.h"
52 #include "osi/include/properties.h"
53 
54 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
55 
56 /*****************************************************************************
57  *  Constants & Macros
58  *****************************************************************************/
59 
60 /* cod value for Headsets */
61 #define COD_AV_HEADSETS 0x0404
62 /* for AVRC 1.4 need to change this */
63 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
64 
65 #define IDX_GET_PLAY_STATUS_RSP 0
66 #define IDX_LIST_APP_ATTR_RSP 1
67 #define IDX_LIST_APP_VALUE_RSP 2
68 #define IDX_GET_CURR_APP_VAL_RSP 3
69 #define IDX_SET_APP_VAL_RSP 4
70 #define IDX_GET_APP_ATTR_TXT_RSP 5
71 #define IDX_GET_APP_VAL_TXT_RSP 6
72 #define IDX_GET_ELEMENT_ATTR_RSP 7
73 #define IDX_SET_ADDR_PLAYER_RSP 8
74 #define IDX_SET_BROWSED_PLAYER_RSP 9
75 #define IDX_GET_FOLDER_ITEMS_RSP 10
76 #define IDX_CHG_PATH_RSP 11
77 #define IDX_GET_ITEM_ATTR_RSP 12
78 #define IDX_PLAY_ITEM_RSP 13
79 #define IDX_GET_TOTAL_NUM_OF_ITEMS_RSP 14
80 #define IDX_SEARCH_RSP 15
81 #define IDX_ADD_TO_NOW_PLAYING_RSP 16
82 
83 /* Update MAX value whenever IDX will be changed */
84 #define MAX_CMD_QUEUE_LEN 17
85 
86 #define MAX_VOLUME 128
87 #define MAX_LABEL 16
88 #define MAX_TRANSACTIONS_PER_SESSION 16
89 #define PLAY_STATUS_PLAYING 1
90 #define BTIF_RC_NUM_CONN BT_RC_NUM_APP
91 
92 #define CHECK_RC_CONNECTED(p_dev)                                          \
93   do {                                                                     \
94     if ((p_dev) == NULL || !(p_dev)->rc_connected) {                       \
95       BTIF_TRACE_WARNING("%s: called when RC is not connected", __func__); \
96       return BT_STATUS_NOT_READY;                                          \
97     }                                                                      \
98   } while (0)
99 
100 #define CHECK_BR_CONNECTED(p_dev)                                          \
101   do {                                                                     \
102     if ((p_dev) == NULL || !(p_dev)->br_connected) {                       \
103       BTIF_TRACE_WARNING("%s: called when BR is not connected", __func__); \
104       return BT_STATUS_NOT_READY;                                          \
105     }                                                                      \
106   } while (0)
107 
108 /*****************************************************************************
109  *  Local type definitions
110  *****************************************************************************/
111 typedef struct {
112   uint8_t bNotify;
113   uint8_t label;
114 } btif_rc_reg_notifications_t;
115 
116 typedef struct {
117   uint8_t label;
118   uint8_t ctype;
119   bool is_rsp_pending;
120 } btif_rc_cmd_ctxt_t;
121 
122 /* 2 second timeout to get interim response */
123 #define BTIF_TIMEOUT_RC_INTERIM_RSP_MS (2 * 1000)
124 #define BTIF_TIMEOUT_RC_STATUS_CMD_MS (2 * 1000)
125 #define BTIF_TIMEOUT_RC_CONTROL_CMD_MS (2 * 1000)
126 
127 typedef enum {
128   eNOT_REGISTERED,
129   eREGISTERED,
130   eINTERIM
131 } btif_rc_nfn_reg_status_t;
132 
133 typedef struct {
134   uint8_t event_id;
135   uint8_t label;
136   btif_rc_nfn_reg_status_t status;
137 } btif_rc_supported_event_t;
138 
139 #define BTIF_RC_STS_TIMEOUT 0xFE
140 typedef struct {
141   uint8_t label;
142   uint8_t pdu_id;
143 } btif_rc_status_cmd_timer_t;
144 
145 typedef struct {
146   uint8_t label;
147   uint8_t pdu_id;
148 } btif_rc_control_cmd_timer_t;
149 
150 typedef struct {
151   union {
152     btif_rc_status_cmd_timer_t rc_status_cmd;
153     btif_rc_control_cmd_timer_t rc_control_cmd;
154   };
155   RawAddress rc_addr;
156 } btif_rc_timer_context_t;
157 
158 typedef struct {
159   bool query_started;
160   uint8_t num_attrs;
161   uint8_t num_ext_attrs;
162 
163   uint8_t attr_index;
164   uint8_t ext_attr_index;
165   uint8_t ext_val_index;
166   btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
167   btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
168 } btif_rc_player_app_settings_t;
169 
170 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single
171  * struct */
172 typedef struct {
173   bool rc_connected;
174   bool br_connected;  // Browsing channel.
175   uint8_t rc_handle;
176   tBTA_AV_FEAT rc_features;
177   btrc_connection_state_t rc_state;
178   RawAddress rc_addr;
179   uint16_t rc_pending_play;
180   btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
181   btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
182   unsigned int rc_volume;
183   uint8_t rc_vol_label;
184   list_t* rc_supported_event_list;
185   btif_rc_player_app_settings_t rc_app_settings;
186   alarm_t* rc_play_status_timer;
187   bool rc_features_processed;
188   uint64_t rc_playing_uid;
189   bool rc_procedure_complete;
190 } btif_rc_device_cb_t;
191 
192 typedef struct {
193   std::mutex lock;
194   btif_rc_device_cb_t rc_multi_cb[BTIF_RC_NUM_CONN];
195 } rc_cb_t;
196 
197 typedef struct {
198   bool in_use;
199   uint8_t lbl;
200   uint8_t handle;
201   btif_rc_timer_context_t txn_timer_context;
202   alarm_t* txn_timer;
203 } rc_transaction_t;
204 
205 typedef struct {
206   std::recursive_mutex lbllock;
207   rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
208 } rc_device_t;
209 
210 typedef struct {
211   uint8_t label;
212   RawAddress rc_addr;
213 } rc_context_t;
214 
215 typedef struct { uint8_t handle; } btif_rc_handle_t;
216 
217 rc_device_t device;
218 
219 static void sleep_ms(period_ms_t timeout_ms);
220 
221 /* Response status code - Unknown Error - this is changed to "reserved" */
222 #define BTIF_STS_GEN_ERROR 0x06
223 
224 /* Utility table to map hal status codes to bta status codes for the response
225  * status */
226 static const uint8_t status_code_map[] = {
227     /* BTA_Status codes        HAL_Status codes */
228     AVRC_STS_BAD_CMD,         /* BTRC_STS_BAD_CMD */
229     AVRC_STS_BAD_PARAM,       /* BTRC_STS_BAD_PARAM */
230     AVRC_STS_NOT_FOUND,       /* BTRC_STS_NOT_FOUND */
231     AVRC_STS_INTERNAL_ERR,    /* BTRC_STS_INTERNAL_ERR */
232     AVRC_STS_NO_ERROR,        /* BTRC_STS_NO_ERROR */
233     AVRC_STS_UID_CHANGED,     /* BTRC_STS_UID_CHANGED */
234     BTIF_STS_GEN_ERROR,       /* BTRC_STS_RESERVED */
235     AVRC_STS_BAD_DIR,         /* BTRC_STS_INV_DIRN */
236     AVRC_STS_NOT_DIR,         /* BTRC_STS_INV_DIRECTORY */
237     AVRC_STS_NOT_EXIST,       /* BTRC_STS_INV_ITEM */
238     AVRC_STS_BAD_SCOPE,       /* BTRC_STS_INV_SCOPE */
239     AVRC_STS_BAD_RANGE,       /* BTRC_STS_INV_RANGE */
240     AVRC_STS_UID_IS_DIR,      /* BTRC_STS_DIRECTORY */
241     AVRC_STS_IN_USE,          /* BTRC_STS_MEDIA_IN_USE */
242     AVRC_STS_NOW_LIST_FULL,   /* BTRC_STS_PLAY_LIST_FULL */
243     AVRC_STS_SEARCH_NOT_SUP,  /* BTRC_STS_SRCH_NOT_SPRTD */
244     AVRC_STS_SEARCH_BUSY,     /* BTRC_STS_SRCH_IN_PROG */
245     AVRC_STS_BAD_PLAYER_ID,   /* BTRC_STS_INV_PLAYER */
246     AVRC_STS_PLAYER_N_BR,     /* BTRC_STS_PLAY_NOT_BROW */
247     AVRC_STS_PLAYER_N_ADDR,   /* BTRC_STS_PLAY_NOT_ADDR */
248     AVRC_STS_BAD_SEARCH_RES,  /* BTRC_STS_INV_RESULTS */
249     AVRC_STS_NO_AVAL_PLAYER,  /* BTRC_STS_NO_AVBL_PLAY */
250     AVRC_STS_ADDR_PLAYER_CHG, /* BTRC_STS_ADDR_PLAY_CHGD */
251 };
252 
253 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu,
254                                  uint8_t status, uint8_t opcode);
255 static uint8_t opcode_from_pdu(uint8_t pdu);
256 static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index,
257                              uint8_t label, tBTA_AV_CODE code,
258                              tAVRC_RESPONSE* pmetamsg_resp);
259 static void register_volumechange(uint8_t label, btif_rc_device_cb_t* p_dev);
260 static void lbl_init();
261 static void init_all_transactions();
262 static bt_status_t get_transaction(rc_transaction_t** ptransaction);
263 static void release_transaction(uint8_t label);
264 static rc_transaction_t* get_transaction_by_lbl(uint8_t label);
265 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg,
266                                   btif_rc_device_cb_t* p_dev);
267 
268 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg);
269 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg);
270 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event,
271                                            tAVRC_COMMAND* pavrc_cmd,
272                                            uint8_t label,
273                                            btif_rc_device_cb_t* p_dev);
274 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev);
275 static void rc_stop_play_status_timer(btif_rc_device_cb_t* p_dev);
276 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
277                                             btif_rc_device_cb_t* p_dev);
278 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg,
279                                            tAVRC_GET_CAPS_RSP* p_rsp);
280 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg,
281                                      tAVRC_LIST_APP_ATTR_RSP* p_rsp);
282 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg,
283                                     tAVRC_LIST_APP_VALUES_RSP* p_rsp);
284 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
285                                         tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp);
286 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
287                                          tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
288 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg,
289                                              tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
290 static void cleanup_app_attr_val_txt_response(
291     btif_rc_player_app_settings_t* p_app_settings);
292 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
293                                            tAVRC_GET_PLAY_STATUS_RSP* p_rsp);
294 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg,
295                                                  tAVRC_RSP* p_rsp);
296 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items,
297                                       uint8_t item_count);
298 static void handle_get_elem_attr_response(tBTA_AV_META_MSG* pmeta_msg,
299                                           tAVRC_GET_ATTRS_RSP* p_rsp);
300 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg,
301                                              tAVRC_RSP* p_rsp);
302 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev);
303 static bt_status_t get_player_app_setting_attr_text_cmd(
304     uint8_t* attrs, uint8_t num_attrs, btif_rc_device_cb_t* p_dev);
305 static bt_status_t get_player_app_setting_value_text_cmd(
306     uint8_t* vals, uint8_t num_vals, btif_rc_device_cb_t* p_dev);
307 static bt_status_t register_notification_cmd(uint8_t label, uint8_t event_id,
308                                              uint32_t event_value,
309                                              btif_rc_device_cb_t* p_dev);
310 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute,
311                                              uint32_t* p_attr_ids,
312                                              btif_rc_device_cb_t* p_dev);
313 static bt_status_t getcapabilities_cmd(uint8_t cap_id,
314                                        btif_rc_device_cb_t* p_dev);
315 static bt_status_t list_player_app_setting_attrib_cmd(
316     btif_rc_device_cb_t* p_dev);
317 static bt_status_t list_player_app_setting_value_cmd(
318     uint8_t attrib_id, btif_rc_device_cb_t* p_dev);
319 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib,
320                                               uint8_t* attrib_ids,
321                                               btif_rc_device_cb_t* p_dev);
322 void get_folder_item_type_media(const tAVRC_ITEM* avrc_item,
323                                 btrc_folder_items_t* btrc_item);
324 void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
325                                  btrc_folder_items_t* btrc_item);
326 void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
327                                  btrc_folder_items_t* btrc_item);
328 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr,
329                                         uint8_t scope, uint32_t start_item,
330                                         uint32_t end_item);
331 
332 static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* p_param,
333                                   uint8_t ctype, uint8_t label,
334                                   btif_rc_device_cb_t* p_dev);
335 
336 static void btif_rc_upstreams_rsp_evt(uint16_t event,
337                                       tAVRC_RESPONSE* pavrc_resp, uint8_t ctype,
338                                       uint8_t label,
339                                       btif_rc_device_cb_t* p_dev);
340 
341 static void rc_start_play_status_timer(btif_rc_device_cb_t* p_dev);
342 static bool absolute_volume_disabled(void);
343 
344 /*****************************************************************************
345  *  Static variables
346  *****************************************************************************/
347 static rc_cb_t btif_rc_cb;
348 static btrc_callbacks_t* bt_rc_callbacks = NULL;
349 static btrc_ctrl_callbacks_t* bt_rc_ctrl_callbacks = NULL;
350 
351 /*****************************************************************************
352  *  Static functions
353  *****************************************************************************/
354 
355 /*****************************************************************************
356  *  Externs
357  *****************************************************************************/
358 extern bool check_cod(const RawAddress& remote_bdaddr, uint32_t cod);
359 
360 /*****************************************************************************
361  *  Functions
362  *****************************************************************************/
alloc_device()363 static btif_rc_device_cb_t* alloc_device() {
364   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
365     if (btif_rc_cb.rc_multi_cb[idx].rc_state ==
366         BTRC_CONNECTION_STATE_DISCONNECTED) {
367       return (&btif_rc_cb.rc_multi_cb[idx]);
368     }
369   }
370   return NULL;
371 }
372 
get_connected_device(int index)373 static btif_rc_device_cb_t* get_connected_device(int index) {
374   BTIF_TRACE_DEBUG("%s: index: %d", __func__, index);
375   if (index > BTIF_RC_NUM_CONN) {
376     BTIF_TRACE_ERROR("%s: can't support more than %d connections", __func__,
377                      BTIF_RC_NUM_CONN);
378     return NULL;
379   }
380   if (btif_rc_cb.rc_multi_cb[index].rc_state !=
381       BTRC_CONNECTION_STATE_CONNECTED) {
382     BTIF_TRACE_ERROR("%s: returning NULL", __func__);
383     return NULL;
384   }
385   return (&btif_rc_cb.rc_multi_cb[index]);
386 }
387 
get_num_connected_devices()388 static int get_num_connected_devices() {
389   int connected_devices = 0;
390   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
391     if (btif_rc_cb.rc_multi_cb[idx].rc_state ==
392         BTRC_CONNECTION_STATE_CONNECTED) {
393       connected_devices++;
394     }
395   }
396   BTIF_TRACE_DEBUG("%s: returning connected_devices: %d", __func__,
397                    connected_devices);
398   return connected_devices;
399 }
400 
btif_rc_get_device_by_bda(const RawAddress & bd_addr)401 btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) {
402   VLOG(1) << __func__ << ": bd_addr: " << bd_addr;
403 
404   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
405     if ((btif_rc_cb.rc_multi_cb[idx].rc_state !=
406          BTRC_CONNECTION_STATE_DISCONNECTED) &&
407         btif_rc_cb.rc_multi_cb[idx].rc_addr == bd_addr) {
408       return (&btif_rc_cb.rc_multi_cb[idx]);
409     }
410   }
411   BTIF_TRACE_ERROR("%s: device not found, returning NULL!", __func__);
412   return NULL;
413 }
414 
btif_rc_get_device_by_handle(uint8_t handle)415 btif_rc_device_cb_t* btif_rc_get_device_by_handle(uint8_t handle) {
416   BTIF_TRACE_DEBUG("%s: handle: 0x%x", __func__, handle);
417   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
418     if ((btif_rc_cb.rc_multi_cb[idx].rc_state !=
419          BTRC_CONNECTION_STATE_DISCONNECTED) &&
420         (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) {
421       BTIF_TRACE_DEBUG("%s: btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x%x",
422                        __func__, btif_rc_cb.rc_multi_cb[idx].rc_handle);
423       return (&btif_rc_cb.rc_multi_cb[idx]);
424     }
425   }
426   BTIF_TRACE_ERROR("%s: returning NULL", __func__);
427   return NULL;
428 }
429 
fill_pdu_queue(int index,uint8_t ctype,uint8_t label,bool pending,btif_rc_device_cb_t * p_dev)430 void fill_pdu_queue(int index, uint8_t ctype, uint8_t label, bool pending,
431                     btif_rc_device_cb_t* p_dev) {
432   p_dev->rc_pdu_info[index].ctype = ctype;
433   p_dev->rc_pdu_info[index].label = label;
434   p_dev->rc_pdu_info[index].is_rsp_pending = pending;
435 }
436 
fill_avrc_attr_entry(tAVRC_ATTR_ENTRY * attr_vals,int num_attrs,btrc_element_attr_val_t * p_attrs)437 void fill_avrc_attr_entry(tAVRC_ATTR_ENTRY* attr_vals, int num_attrs,
438                           btrc_element_attr_val_t* p_attrs) {
439   for (int attr_cnt = 0; attr_cnt < num_attrs; attr_cnt++) {
440     attr_vals[attr_cnt].attr_id = p_attrs[attr_cnt].attr_id;
441     attr_vals[attr_cnt].name.charset_id = AVRC_CHARSET_ID_UTF8;
442     attr_vals[attr_cnt].name.str_len =
443         (uint16_t)strlen((char*)p_attrs[attr_cnt].text);
444     attr_vals[attr_cnt].name.p_str = p_attrs[attr_cnt].text;
445     BTIF_TRACE_DEBUG(
446         "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__,
447         (unsigned int)attr_vals[attr_cnt].attr_id,
448         attr_vals[attr_cnt].name.charset_id, attr_vals[attr_cnt].name.str_len,
449         attr_vals[attr_cnt].name.p_str);
450   }
451 }
452 
rc_cleanup_sent_cmd(void * p_data)453 void rc_cleanup_sent_cmd(void* p_data) { BTIF_TRACE_DEBUG("%s: ", __func__); }
454 
handle_rc_ctrl_features(btif_rc_device_cb_t * p_dev)455 void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) {
456   if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG) &&
457       (!(p_dev->rc_features & BTA_AV_FEAT_RCCT) ||
458        !(p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL))) {
459     return;
460   }
461 
462   int rc_features = 0;
463 
464   if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) &&
465       (p_dev->rc_features & BTA_AV_FEAT_RCCT)) {
466     rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
467   }
468 
469   if ((p_dev->rc_features & BTA_AV_FEAT_METADATA) &&
470       (p_dev->rc_features & BTA_AV_FEAT_VENDOR) &&
471       (p_dev->rc_features_processed != true)) {
472     rc_features |= BTRC_FEAT_METADATA;
473 
474     /* Mark rc features processed to avoid repeating
475      * the AVRCP procedure every time on receiving this
476      * update.
477      */
478     p_dev->rc_features_processed = true;
479     if (btif_av_is_sink_enabled()) {
480       getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
481     }
482   }
483 
484   /* Add browsing feature capability */
485   if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) {
486     rc_features |= BTRC_FEAT_BROWSE;
487   }
488 
489   BTIF_TRACE_DEBUG("%s: Update rc features to CTRL: %d", __func__, rc_features);
490   do_in_jni_thread(FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->getrcfeatures_cb,
491                                          p_dev->rc_addr, rc_features));
492 }
493 
handle_rc_features(btif_rc_device_cb_t * p_dev)494 void handle_rc_features(btif_rc_device_cb_t* p_dev) {
495 
496   CHECK(bt_rc_callbacks);
497 
498   btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
499   RawAddress avdtp_source_active_peer_addr = btif_av_source_active_peer();
500   RawAddress avdtp_sink_active_peer_addr = btif_av_sink_active_peer();
501 
502   BTIF_TRACE_DEBUG(
503       "%s: AVDTP Source Active Peer Address: %s "
504       "AVDTP Sink Active Peer Address: %s "
505       "AVCTP address: %s",
506       __func__, avdtp_source_active_peer_addr.ToString().c_str(),
507       avdtp_sink_active_peer_addr.ToString().c_str(),
508       p_dev->rc_addr.ToString().c_str());
509 
510   if (interop_match_addr(INTEROP_DISABLE_ABSOLUTE_VOLUME, &p_dev->rc_addr) ||
511       absolute_volume_disabled() ||
512       (avdtp_source_active_peer_addr != p_dev->rc_addr &&
513        avdtp_sink_active_peer_addr != p_dev->rc_addr)) {
514     p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
515   }
516 
517   if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) {
518     rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_BROWSE);
519   }
520 
521 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
522   if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) &&
523       (p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
524     rc_features =
525         (btrc_remote_features_t)(rc_features | BTRC_FEAT_ABSOLUTE_VOLUME);
526   }
527 #endif
528 
529   if (p_dev->rc_features & BTA_AV_FEAT_METADATA) {
530     rc_features = (btrc_remote_features_t)(rc_features | BTRC_FEAT_METADATA);
531   }
532 
533   BTIF_TRACE_DEBUG("%s: rc_features: 0x%x", __func__, rc_features);
534   HAL_CBACK(bt_rc_callbacks, remote_features_cb, p_dev->rc_addr, rc_features);
535 
536 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
537   BTIF_TRACE_DEBUG(
538       "%s: Checking for feature flags in btif_rc_handler with label: %d",
539       __func__, p_dev->rc_vol_label);
540   // Register for volume change on connect
541   if (p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL &&
542       p_dev->rc_features & BTA_AV_FEAT_RCTG) {
543     rc_transaction_t* p_transaction = NULL;
544     bt_status_t status = BT_STATUS_NOT_READY;
545     if (MAX_LABEL == p_dev->rc_vol_label) {
546       status = get_transaction(&p_transaction);
547     } else {
548       p_transaction = get_transaction_by_lbl(p_dev->rc_vol_label);
549       if (NULL != p_transaction) {
550         BTIF_TRACE_DEBUG(
551             "%s: register_volumechange already in progress for label: %d",
552             __func__, p_dev->rc_vol_label);
553         return;
554       }
555       status = get_transaction(&p_transaction);
556     }
557     if (BT_STATUS_SUCCESS == status && NULL != p_transaction) {
558       p_dev->rc_vol_label = p_transaction->lbl;
559       register_volumechange(p_dev->rc_vol_label, p_dev);
560     }
561   }
562 #endif
563 }
564 
565 /***************************************************************************
566  *  Function       handle_rc_connect
567  *
568  *  - Argument:    tBTA_AV_RC_OPEN  browse RC open data structure
569  *
570  *  - Description: browse RC connection event handler
571  *
572  ***************************************************************************/
handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN * p_rc_br_open)573 void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) {
574   BTIF_TRACE_DEBUG("%s: rc_handle %d status %d", __func__,
575                    p_rc_br_open->rc_handle, p_rc_br_open->status);
576   btif_rc_device_cb_t* p_dev =
577       btif_rc_get_device_by_handle(p_rc_br_open->rc_handle);
578 
579   if (!p_dev) {
580     BTIF_TRACE_ERROR("%s p_dev is null", __func__);
581     return;
582   }
583 
584   /* check that we are already connected to this address since being connected
585    * to a browse when not connected to the control channel over AVRCP is
586    * probably not preferred anyways. */
587   if (p_rc_br_open->status == BTA_AV_SUCCESS) {
588     p_dev->br_connected = true;
589     do_in_jni_thread(FROM_HERE,
590                      base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true,
591                                 true, p_dev->rc_addr));
592   }
593 }
594 
595 /***************************************************************************
596  *  Function       handle_rc_connect
597  *
598  *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
599  *
600  *  - Description: RC connection event handler
601  *
602  ***************************************************************************/
handle_rc_connect(tBTA_AV_RC_OPEN * p_rc_open)603 void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) {
604   BTIF_TRACE_DEBUG("%s: rc_handle: %d", __func__, p_rc_open->rc_handle);
605 
606   btif_rc_device_cb_t* p_dev = alloc_device();
607   if (p_dev == NULL) {
608     BTIF_TRACE_ERROR("%s: p_dev is NULL", __func__);
609     return;
610   }
611 
612   if (!(p_rc_open->status == BTA_AV_SUCCESS)) {
613     BTIF_TRACE_ERROR("%s: Connect failed with error code: %d", __func__,
614                      p_rc_open->status);
615     p_dev->rc_connected = false;
616   }
617 
618   // check if already some RC is connected
619   if (p_dev->rc_connected) {
620     BTIF_TRACE_ERROR(
621         "%s: Got RC OPEN in connected state, Connected RC: %d \
622             and Current RC: %d",
623         __func__, p_dev->rc_handle, p_rc_open->rc_handle);
624     if (p_dev->rc_handle != p_rc_open->rc_handle &&
625         p_dev->rc_addr != p_rc_open->peer_addr) {
626       BTIF_TRACE_DEBUG("%s: Got RC connected for some other handle", __func__);
627       BTA_AvCloseRc(p_rc_open->rc_handle);
628       return;
629     }
630   }
631   p_dev->rc_addr = p_rc_open->peer_addr;
632   p_dev->rc_features = p_rc_open->peer_features;
633   BTIF_TRACE_DEBUG("%s: handle_rc_connect in features: 0x%x out features 0x%x",
634                    __func__, p_rc_open->peer_features, p_dev->rc_features);
635   p_dev->rc_vol_label = MAX_LABEL;
636   p_dev->rc_volume = MAX_VOLUME;
637 
638   p_dev->rc_connected = true;
639   p_dev->rc_handle = p_rc_open->rc_handle;
640   p_dev->rc_state = BTRC_CONNECTION_STATE_CONNECTED;
641   /* on locally initiated connection we will get remote features as part of
642    * connect */
643   if (p_dev->rc_features != 0 && bt_rc_callbacks != NULL) {
644     handle_rc_features(p_dev);
645   }
646 
647   p_dev->rc_playing_uid = RC_INVALID_TRACK_ID;
648   if (bt_rc_ctrl_callbacks != NULL) {
649     do_in_jni_thread(FROM_HERE,
650                      base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, true,
651                                 false, p_dev->rc_addr));
652   }
653   /* report connection state if remote device is AVRCP target */
654   handle_rc_ctrl_features(p_dev);
655 }
656 
657 /***************************************************************************
658  *  Function       handle_rc_disconnect
659  *
660  *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
661  *
662  *  - Description: RC disconnection event handler
663  *
664  ***************************************************************************/
handle_rc_disconnect(tBTA_AV_RC_CLOSE * p_rc_close)665 void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) {
666   btif_rc_device_cb_t* p_dev = NULL;
667   BTIF_TRACE_DEBUG("%s: rc_handle: %d", __func__, p_rc_close->rc_handle);
668 
669   p_dev = btif_rc_get_device_by_handle(p_rc_close->rc_handle);
670   if (p_dev == NULL) {
671     BTIF_TRACE_ERROR("%s: Got disconnect from invalid rc handle", __func__);
672     return;
673   }
674 
675   if (p_rc_close->rc_handle != p_dev->rc_handle &&
676       p_dev->rc_addr != p_rc_close->peer_addr) {
677     BTIF_TRACE_ERROR("Got disconnect of unknown device");
678     return;
679   }
680   /* report connection state if device is AVRCP target */
681   if (bt_rc_ctrl_callbacks != NULL) {
682     do_in_jni_thread(
683         FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->connection_state_cb, false,
684                               false, p_dev->rc_addr));
685   }
686   /* Clean up AVRCP procedure flags */
687   memset(&p_dev->rc_app_settings, 0, sizeof(btif_rc_player_app_settings_t));
688   p_dev->rc_features_processed = false;
689   p_dev->rc_procedure_complete = false;
690   rc_stop_play_status_timer(p_dev);
691   /* Check and clear the notification event list */
692   if (p_dev->rc_supported_event_list != NULL) {
693     list_clear(p_dev->rc_supported_event_list);
694     p_dev->rc_supported_event_list = NULL;
695   }
696 
697   /* check if there is another device connected */
698   if (p_dev->rc_state == BTRC_CONNECTION_STATE_CONNECTED) {
699     p_dev->rc_handle = 0;
700     p_dev->rc_connected = false;
701     p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
702 
703     memset(p_dev->rc_notif, 0, sizeof(p_dev->rc_notif));
704 
705     p_dev->rc_features = 0;
706     p_dev->rc_vol_label = MAX_LABEL;
707     p_dev->rc_volume = MAX_VOLUME;
708 
709     p_dev->rc_addr = RawAddress::kEmpty;
710   }
711   if (get_num_connected_devices() == 0) {
712     BTIF_TRACE_DEBUG("%s: Closing all handles", __func__);
713     init_all_transactions();
714   }
715 
716   p_dev->rc_addr = RawAddress::kEmpty;
717 }
718 
719 /***************************************************************************
720  *  Function       handle_rc_passthrough_cmd
721  *
722  *  - Argument:    tBTA_AV_RC rc_id   remote control command ID
723  *                 tBTA_AV_STATE key_state status of key press
724  *
725  *  - Description: Remote control command handler
726  *
727  ***************************************************************************/
handle_rc_passthrough_cmd(tBTA_AV_REMOTE_CMD * p_remote_cmd)728 void handle_rc_passthrough_cmd(tBTA_AV_REMOTE_CMD* p_remote_cmd) {
729   if (p_remote_cmd == NULL) {
730     BTIF_TRACE_ERROR("%s: No remote command!", __func__);
731     return;
732   }
733 
734   btif_rc_device_cb_t* p_dev =
735       btif_rc_get_device_by_handle(p_remote_cmd->rc_handle);
736   if (p_dev == NULL) {
737     BTIF_TRACE_ERROR("%s: Got passthrough command from invalid rc handle",
738                      __func__);
739     return;
740   }
741 
742 
743   BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id: %d", __func__,
744                    p_remote_cmd->rc_id);
745 
746   /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up
747    * this PLAY */
748   if ((p_remote_cmd->rc_id == AVRC_ID_PLAY) && (!btif_av_is_connected())) {
749     if (p_remote_cmd->key_state == AVRC_STATE_PRESS) {
750       APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command",
751                          __func__);
752       p_dev->rc_pending_play = true;
753     }
754     return;
755   }
756 
757   /* If we previously queued a play and we get a PAUSE, clear it. */
758   if ((p_remote_cmd->rc_id == AVRC_ID_PAUSE) && (p_dev->rc_pending_play)) {
759     APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received",
760                        __func__);
761     p_dev->rc_pending_play = false;
762     return;
763   }
764 
765   if ((p_remote_cmd->rc_id == AVRC_ID_STOP) &&
766       (!btif_av_stream_started_ready())) {
767     APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd", __func__);
768     return;
769   }
770 
771   int pressed = (p_remote_cmd->key_state == AVRC_STATE_PRESS) ? 1 : 0;
772 
773   /* pass all commands up */
774   BTIF_TRACE_DEBUG("%s: rc_features: %d, cmd->rc_id: %d, pressed: %d", __func__,
775                    p_dev->rc_features, p_remote_cmd->rc_id, pressed);
776   HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed,
777             p_dev->rc_addr);
778 }
779 
780 /***************************************************************************
781  *  Function       handle_rc_passthrough_rsp
782  *
783  *  - Argument:    tBTA_AV_REMOTE_RSP passthrough command response
784  *
785  *  - Description: Remote control passthrough response handler
786  *
787  ***************************************************************************/
handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)788 void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
789   btif_rc_device_cb_t* p_dev = NULL;
790 
791   p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
792   if (p_dev == NULL) {
793     BTIF_TRACE_ERROR("%s: passthrough response for Invalid rc handle",
794                      __func__);
795     return;
796   }
797 
798 
799   if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
800     BTIF_TRACE_ERROR("%s: DUT does not support AVRCP controller role",
801                      __func__);
802     return;
803   }
804 
805   const char* status = (p_remote_rsp->key_state == 1) ? "released" : "pressed";
806   BTIF_TRACE_DEBUG("%s: rc_id: %d state: %s", __func__, p_remote_rsp->rc_id,
807                    status);
808 
809   release_transaction(p_remote_rsp->label);
810   if (bt_rc_ctrl_callbacks != NULL) {
811     do_in_jni_thread(
812         FROM_HERE,
813         base::Bind(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr,
814                    p_remote_rsp->rc_id, p_remote_rsp->key_state));
815   }
816 }
817 
818 /***************************************************************************
819  *  Function       handle_rc_vendorunique_rsp
820  *
821  *  - Argument:    tBTA_AV_REMOTE_RSP  command response
822  *
823  *  - Description: Remote control vendor unique response handler
824  *
825  ***************************************************************************/
handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)826 void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
827   btif_rc_device_cb_t* p_dev = NULL;
828   const char* status;
829   uint8_t vendor_id = 0;
830 
831   p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
832   if (p_dev == NULL) {
833     BTIF_TRACE_ERROR("%s: Got vendorunique rsp from invalid rc handle",
834                      __func__);
835     return;
836   }
837 
838   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
839     int key_state;
840     if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) {
841       status = "released";
842       key_state = 1;
843     } else {
844       status = "pressed";
845       key_state = 0;
846     }
847 
848     if (p_remote_rsp->len > 0) {
849       if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN)
850         vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN - 1];
851       osi_free_and_reset((void**)&p_remote_rsp->p_data);
852     }
853     BTIF_TRACE_DEBUG("%s: vendor_id: %d status: %s", __func__, vendor_id,
854                      status);
855 
856     release_transaction(p_remote_rsp->label);
857     do_in_jni_thread(FROM_HERE,
858                      base::Bind(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb,
859                                 vendor_id, key_state));
860   } else {
861     BTIF_TRACE_ERROR("%s: Remote does not support AVRCP TG role", __func__);
862   }
863 }
864 
865 /***************************************************************************
866  *  Function       handle_rc_metamsg_cmd
867  *
868  *  - Argument:    tBTA_AV_VENDOR Structure containing the received
869  *                          metamsg command
870  *
871  *  - Description: Remote control metamsg command handler (AVRCP 1.3)
872  *
873  ***************************************************************************/
handle_rc_metamsg_cmd(tBTA_AV_META_MSG * pmeta_msg)874 void handle_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) {
875   /* Parse the metamsg command and pass it on to BTL-IFS */
876   uint8_t scratch_buf[512] = {0};
877   tAVRC_COMMAND avrc_command = {0};
878   tAVRC_STS status;
879   btif_rc_device_cb_t* p_dev = NULL;
880 
881   if (NULL == pmeta_msg) {
882     BTIF_TRACE_EVENT("%s: Exiting as pmeta_msg is NULL", __func__);
883     return;
884   }
885 
886   if (NULL == pmeta_msg->p_msg) {
887     BTIF_TRACE_EVENT("%s: Exiting as pmeta_msg->p_msg is NULL", __func__);
888     return;
889   }
890 
891   BTIF_TRACE_EVENT("%s: pmeta_msg: opcode: %x, code: %x", __func__,
892                    pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
893 
894   p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
895   if (p_dev == NULL) {
896     BTIF_TRACE_ERROR("%s: Meta msg event for Invalid rc handle", __func__);
897     return;
898   }
899 
900   if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR &&
901       pmeta_msg->p_msg->hdr.opcode != AVRC_OP_BROWSE) {
902     BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
903     return;
904   }
905 
906   if (pmeta_msg->len < 3) {
907     BTIF_TRACE_WARNING("%s: Invalid length. opcode: 0x%x, len: 0x%x", __func__,
908                        pmeta_msg->p_msg->hdr.opcode, pmeta_msg->len);
909     return;
910   }
911 
912   if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) {
913     {
914       rc_transaction_t* transaction = NULL;
915       transaction = get_transaction_by_lbl(pmeta_msg->label);
916       if (transaction != NULL) {
917         handle_rc_metamsg_rsp(pmeta_msg, p_dev);
918       } else {
919         BTIF_TRACE_DEBUG(
920             "%s: Discard vendor dependent rsp. code: %d label: %d.", __func__,
921             pmeta_msg->code, pmeta_msg->label);
922       }
923       return;
924     }
925   }
926 
927   status = AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf,
928                             sizeof(scratch_buf));
929   BTIF_TRACE_DEBUG("%s: Received vendor command.code,PDU and label: %d, %d, %d",
930                    __func__, pmeta_msg->code, avrc_command.cmd.pdu,
931                    pmeta_msg->label);
932 
933   if (status != AVRC_STS_NO_ERROR) {
934     /* return error */
935     BTIF_TRACE_WARNING(
936         "%s: Error in parsing received metamsg command. status: 0x%02x",
937         __func__, status);
938     send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label,
939                          avrc_command.pdu, status,
940                          pmeta_msg->p_msg->hdr.opcode);
941   } else {
942     /* if RegisterNotification, add it to our registered queue */
943 
944     if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
945       uint8_t event_id = avrc_command.reg_notif.event_id;
946 
947       BTIF_TRACE_EVENT(
948           "%s: New register notification received.event_id: %s, label: 0x%x, "
949           "code: %x",
950           __func__, dump_rc_notification_event_id(event_id), pmeta_msg->label,
951           pmeta_msg->code);
952       p_dev->rc_notif[event_id - 1].bNotify = true;
953       p_dev->rc_notif[event_id - 1].label = pmeta_msg->label;
954     }
955 
956     BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
957                      __func__, dump_rc_pdu(avrc_command.cmd.pdu));
958 
959     /* Since handle_rc_metamsg_cmd() itself is called from
960         *btif context, no context switching is required. Invoke
961         * btif_rc_upstreams_evt directly from here. */
962     btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command,
963                           pmeta_msg->code, pmeta_msg->label, p_dev);
964   }
965 }
966 
967 /***************************************************************************
968  **
969  ** Function       btif_rc_handler
970  **
971  ** Description    RC event handler
972  **
973  ***************************************************************************/
btif_rc_handler(tBTA_AV_EVT event,tBTA_AV * p_data)974 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) {
975   BTIF_TRACE_DEBUG("%s: event: %s", __func__, dump_rc_event(event));
976   btif_rc_device_cb_t* p_dev = NULL;
977   switch (event) {
978     case BTA_AV_RC_OPEN_EVT: {
979       BTIF_TRACE_DEBUG("%s: Peer_features: %x", __func__,
980                        p_data->rc_open.peer_features);
981       handle_rc_connect(&(p_data->rc_open));
982     } break;
983 
984     case BTA_AV_RC_BROWSE_OPEN_EVT: {
985       /* tell the UL that we have connection to browse channel and that
986        * browse commands can be directed accordingly. */
987       handle_rc_browse_connect(&p_data->rc_browse_open);
988     } break;
989 
990     case BTA_AV_RC_CLOSE_EVT: {
991       handle_rc_disconnect(&(p_data->rc_close));
992     } break;
993 
994     case BTA_AV_RC_BROWSE_CLOSE_EVT: {
995       BTIF_TRACE_DEBUG("%s: BTA_AV_RC_BROWSE_CLOSE_EVT", __func__);
996     } break;
997 
998     case BTA_AV_REMOTE_CMD_EVT: {
999       if (bt_rc_callbacks != NULL) {
1000         BTIF_TRACE_DEBUG("%s: rc_id: 0x%x key_state: %d", __func__,
1001                          p_data->remote_cmd.rc_id,
1002                          p_data->remote_cmd.key_state);
1003         handle_rc_passthrough_cmd((&p_data->remote_cmd));
1004       } else {
1005         BTIF_TRACE_ERROR("%s: AVRCP TG role not up, drop passthrough commands",
1006                          __func__);
1007       }
1008     } break;
1009 
1010     case BTA_AV_REMOTE_RSP_EVT: {
1011       BTIF_TRACE_DEBUG("%s: RSP: rc_id: 0x%x key_state: %d", __func__,
1012                        p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state);
1013 
1014       if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) {
1015         handle_rc_vendorunique_rsp((&p_data->remote_rsp));
1016       } else {
1017         handle_rc_passthrough_rsp((&p_data->remote_rsp));
1018       }
1019     } break;
1020 
1021     case BTA_AV_RC_FEAT_EVT: {
1022       BTIF_TRACE_DEBUG("%s: Peer_features: %x", __func__,
1023                        p_data->rc_feat.peer_features);
1024       p_dev = btif_rc_get_device_by_handle(p_data->rc_feat.rc_handle);
1025       if (p_dev == NULL) {
1026         BTIF_TRACE_ERROR("%s: RC Feature event for Invalid rc handle",
1027                          __func__);
1028         break;
1029       }
1030 
1031       p_dev->rc_features = p_data->rc_feat.peer_features;
1032       if (bt_rc_callbacks != NULL) {
1033         handle_rc_features(p_dev);
1034       }
1035 
1036       if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) {
1037         handle_rc_ctrl_features(p_dev);
1038       }
1039     } break;
1040 
1041     case BTA_AV_META_MSG_EVT: {
1042       if (bt_rc_callbacks != NULL) {
1043         BTIF_TRACE_DEBUG("%s: BTA_AV_META_MSG_EVT code: %d label: %d", __func__,
1044                          p_data->meta_msg.code, p_data->meta_msg.label);
1045         BTIF_TRACE_DEBUG("%s: company_id: 0x%x len: %d handle: %d", __func__,
1046                          p_data->meta_msg.company_id, p_data->meta_msg.len,
1047                          p_data->meta_msg.rc_handle);
1048 
1049         /* handle the metamsg command */
1050         handle_rc_metamsg_cmd(&(p_data->meta_msg));
1051 
1052         /* Free the Memory allocated for tAVRC_MSG */
1053       } else if (bt_rc_ctrl_callbacks != NULL) {
1054         /* This is case of Sink + CT + TG(for abs vol)) */
1055         BTIF_TRACE_DEBUG(
1056             "%s BTA_AV_META_MSG_EVT code:%d label:%d opcode %d ctype %d",
1057             __func__, p_data->meta_msg.code, p_data->meta_msg.label,
1058             p_data->meta_msg.p_msg->hdr.opcode,
1059             p_data->meta_msg.p_msg->hdr.ctype);
1060         BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d", __func__,
1061                          p_data->meta_msg.company_id, p_data->meta_msg.len,
1062                          p_data->meta_msg.rc_handle);
1063         switch (p_data->meta_msg.p_msg->hdr.opcode) {
1064           case AVRC_OP_VENDOR:
1065             if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL) &&
1066                 (p_data->meta_msg.code <= AVRC_RSP_INTERIM)) {
1067               /* Its a response */
1068               handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
1069             } else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ) {
1070               /* Its a command  */
1071               handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
1072             }
1073             break;
1074 
1075           case AVRC_OP_BROWSE:
1076             if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_CMD) {
1077               handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
1078             } else if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_RSP) {
1079               handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
1080             }
1081             break;
1082         }
1083       } else {
1084         BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands");
1085       }
1086     } break;
1087 
1088     default:
1089       BTIF_TRACE_DEBUG("%s: Unhandled RC event : 0x%x", __func__, event);
1090   }
1091 }
1092 
btif_rc_is_connected_peer(const RawAddress & peer_addr)1093 bool btif_rc_is_connected_peer(const RawAddress& peer_addr) {
1094   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1095     btif_rc_device_cb_t* p_dev = get_connected_device(idx);
1096     if (p_dev != NULL && (p_dev->rc_connected == TRUE) &&
1097         peer_addr == p_dev->rc_addr) {
1098       return true;
1099     }
1100   }
1101   return false;
1102 }
1103 
1104 /***************************************************************************
1105  **
1106  ** Function       btif_rc_get_connected_peer_handle
1107  **
1108  ** Description    Fetches the connected headset's handle if any
1109  **
1110  ***************************************************************************/
btif_rc_get_connected_peer_handle(const RawAddress & peer_addr)1111 uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) {
1112   btif_rc_device_cb_t* p_dev = NULL;
1113   p_dev = btif_rc_get_device_by_bda(peer_addr);
1114 
1115   if (p_dev == NULL) {
1116     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
1117     return BTRC_HANDLE_NONE;
1118   }
1119   return p_dev->rc_handle;
1120 }
1121 
1122 /***************************************************************************
1123  **
1124  ** Function       btif_rc_check_handle_pending_play
1125  **
1126  ** Description    Clears the queued PLAY command. if |bSendToApp| is true,
1127  **                forwards to app
1128  **
1129  ***************************************************************************/
1130 
1131 /* clear the queued PLAY command. if |bSendToApp| is true, forward to app */
btif_rc_check_handle_pending_play(const RawAddress & peer_addr,bool bSendToApp)1132 void btif_rc_check_handle_pending_play(const RawAddress& peer_addr,
1133                                        bool bSendToApp) {
1134   btif_rc_device_cb_t* p_dev = NULL;
1135   p_dev = btif_rc_get_device_by_bda(peer_addr);
1136 
1137   if (p_dev == NULL) {
1138     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
1139     return;
1140   }
1141 
1142   BTIF_TRACE_DEBUG("%s: bSendToApp: %d", __func__, bSendToApp);
1143   if (p_dev->rc_pending_play) {
1144     if (bSendToApp) {
1145       tBTA_AV_REMOTE_CMD remote_cmd;
1146       APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __func__);
1147 
1148       memset(&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
1149       remote_cmd.rc_handle = p_dev->rc_handle;
1150       remote_cmd.rc_id = AVRC_ID_PLAY;
1151       remote_cmd.hdr.ctype = AVRC_CMD_CTRL;
1152       remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
1153 
1154       /* delay sending to app, else there is a timing issue in the framework,
1155        ** which causes the audio to be on th device's speaker. Delay between
1156        ** OPEN & RC_PLAYs
1157       */
1158       sleep_ms(200);
1159       /* send to app - both PRESSED & RELEASED */
1160       remote_cmd.key_state = AVRC_STATE_PRESS;
1161       handle_rc_passthrough_cmd(&remote_cmd);
1162 
1163       sleep_ms(100);
1164 
1165       remote_cmd.key_state = AVRC_STATE_RELEASE;
1166       handle_rc_passthrough_cmd(&remote_cmd);
1167     }
1168     p_dev->rc_pending_play = false;
1169   }
1170 }
1171 
1172 /* Generic reject response */
send_reject_response(uint8_t rc_handle,uint8_t label,uint8_t pdu,uint8_t status,uint8_t opcode)1173 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu,
1174                                  uint8_t status, uint8_t opcode) {
1175   uint8_t ctype = AVRC_RSP_REJ;
1176   tAVRC_RESPONSE avrc_rsp;
1177   BT_HDR* p_msg = NULL;
1178   memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1179 
1180   avrc_rsp.rsp.opcode = opcode;
1181   avrc_rsp.rsp.pdu = pdu;
1182   avrc_rsp.rsp.status = status;
1183 
1184   status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg);
1185 
1186   if (status != AVRC_STS_NO_ERROR) {
1187     BTIF_TRACE_ERROR("%s: status not AVRC_STS_NO_ERROR", __func__);
1188     return;
1189   }
1190 
1191   BTIF_TRACE_DEBUG(
1192       "%s: Sending error notification to handle: %d. pdu: %s,status: 0x%02x",
1193       __func__, rc_handle, dump_rc_pdu(pdu), status);
1194   BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1195 }
1196 
1197 /***************************************************************************
1198  *  Function         get_rsp_type_code
1199  *
1200  *  - Argument:   status
1201  *  - Description: Returns response type codes for particular command code and
1202  *                 status.
1203  *
1204  ***************************************************************************/
get_rsp_type_code(tAVRC_STS status,tBTA_AV_CODE code)1205 static tBTA_AV_CODE get_rsp_type_code(tAVRC_STS status, tBTA_AV_CODE code) {
1206   if (status != AVRC_STS_NO_ERROR) {
1207     return AVRC_RSP_REJ;
1208   }
1209 
1210   if (code < AVRC_RSP_NOT_IMPL) {
1211     if (code == AVRC_CMD_NOTIF) return AVRC_RSP_INTERIM;
1212 
1213     if (code == AVRC_CMD_STATUS) return AVRC_RSP_IMPL_STBL;
1214 
1215     return AVRC_RSP_ACCEPT;
1216   }
1217 
1218   return code;
1219 }
1220 
1221 /***************************************************************************
1222  *  Function       send_metamsg_rsp
1223  *
1224  *  - Argument:
1225  *                  p_dev           Dev pointer
1226  *                  index           Command index (= -1 if not used)
1227  *                  label           Label of the RC response
1228  *                  code            Response type
1229  *                  pmetamsg_resp   Vendor response
1230  *
1231  *  - Description: Remote control metamsg response handler
1232  *
1233  ***************************************************************************/
send_metamsg_rsp(btif_rc_device_cb_t * p_dev,int index,uint8_t label,tBTA_AV_CODE code,tAVRC_RESPONSE * pmetamsg_resp)1234 static void send_metamsg_rsp(btif_rc_device_cb_t* p_dev, int index,
1235                              uint8_t label, tBTA_AV_CODE code,
1236                              tAVRC_RESPONSE* pmetamsg_resp) {
1237   uint8_t ctype;
1238 
1239   if (p_dev == NULL) {
1240     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
1241     return;
1242   }
1243 
1244   if (pmetamsg_resp == NULL) {
1245     BTIF_TRACE_WARNING("%s: Invalid response received from application",
1246                        __func__);
1247     return;
1248   }
1249 
1250   BTIF_TRACE_EVENT(
1251       "%s: rc_handle: %d, index: %d, label: %d, code: 0x%02x, pdu: %s",
1252       __func__, p_dev->rc_handle, index, label, code,
1253       dump_rc_pdu(pmetamsg_resp->rsp.pdu));
1254 
1255   if (index >= 0 && !p_dev->rc_pdu_info[index].is_rsp_pending) {
1256     BTIF_TRACE_ERROR("%s: is_rsp_pending false, returning", __func__);
1257     return;
1258   }
1259 
1260   ctype = get_rsp_type_code(pmetamsg_resp->rsp.status, code);
1261 
1262   /* if response is for register_notification, make sure the rc has
1263   actually registered for this */
1264   if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) &&
1265       ((code == AVRC_RSP_CHANGED) || (code == AVRC_RSP_INTERIM))) {
1266     bool bSent = false;
1267     uint8_t event_id = pmetamsg_resp->reg_notif.event_id;
1268     bool bNotify =
1269         (p_dev->rc_connected) && (p_dev->rc_notif[event_id - 1].bNotify);
1270 
1271     /* de-register this notification for a CHANGED response */
1272     p_dev->rc_notif[event_id - 1].bNotify = false;
1273     BTIF_TRACE_DEBUG("%s: rc_handle: %d. event_id: 0x%02d bNotify: %u",
1274                      __func__, p_dev->rc_handle, event_id, bNotify);
1275     if (bNotify) {
1276       BT_HDR* p_msg = NULL;
1277       tAVRC_STS status;
1278 
1279       if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(
1280                                     p_dev->rc_handle, pmetamsg_resp, &p_msg))) {
1281         BTIF_TRACE_DEBUG(
1282             "%s: Sending notification to rc_handle: %d. event_id: 0x%02d",
1283             __func__, p_dev->rc_handle, event_id);
1284         bSent = true;
1285         BTA_AvMetaRsp(p_dev->rc_handle, p_dev->rc_notif[event_id - 1].label,
1286                       ctype, p_msg);
1287       } else {
1288         BTIF_TRACE_WARNING(
1289             "%s: failed to build metamsg response. status: 0x%02x", __func__,
1290             status);
1291       }
1292     }
1293 
1294     if (!bSent) {
1295       BTIF_TRACE_DEBUG(
1296           "%s: Notification not sent, as there are no RC connections or the \
1297                 CT has not subscribed for event_id: %s",
1298           __func__, dump_rc_notification_event_id(event_id));
1299     }
1300   } else {
1301     /* All other commands go here */
1302 
1303     BT_HDR* p_msg = NULL;
1304     tAVRC_STS status;
1305 
1306     status = AVRC_BldResponse(p_dev->rc_handle, pmetamsg_resp, &p_msg);
1307 
1308     if (status == AVRC_STS_NO_ERROR) {
1309       BTA_AvMetaRsp(p_dev->rc_handle, label, ctype, p_msg);
1310     } else {
1311       BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1312                        __func__, status);
1313     }
1314   }
1315 
1316   if (index >= 0) {
1317     p_dev->rc_pdu_info[index].ctype = 0;
1318     p_dev->rc_pdu_info[index].label = 0;
1319     p_dev->rc_pdu_info[index].is_rsp_pending = false;
1320   }
1321 }
1322 
opcode_from_pdu(uint8_t pdu)1323 static uint8_t opcode_from_pdu(uint8_t pdu) {
1324   uint8_t opcode = 0;
1325 
1326   switch (pdu) {
1327     case AVRC_PDU_SET_BROWSED_PLAYER:
1328     case AVRC_PDU_GET_FOLDER_ITEMS:
1329     case AVRC_PDU_CHANGE_PATH:
1330     case AVRC_PDU_GET_ITEM_ATTRIBUTES:
1331     case AVRC_PDU_ADD_TO_NOW_PLAYING:
1332     case AVRC_PDU_SEARCH:
1333     case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS:
1334     case AVRC_PDU_GENERAL_REJECT:
1335       opcode = AVRC_OP_BROWSE;
1336       break;
1337 
1338     case AVRC_PDU_NEXT_GROUP:
1339     case AVRC_PDU_PREV_GROUP: /* pass thru */
1340       opcode = AVRC_OP_PASS_THRU;
1341       break;
1342 
1343     default: /* vendor */
1344       opcode = AVRC_OP_VENDOR;
1345       break;
1346   }
1347 
1348   return opcode;
1349 }
1350 
1351 /***************************************************************************
1352  * Function:  fill_attribute_id_array
1353  *
1354  * - Argument:
1355  *     cmd_attribute_number         input attribute number from AVRCP command
1356  *     cmd_attribute_id_array       input attribute list from AVRCP command
1357  *     out_array_size               allocated size of out attribute id array
1358  *     out_attribute_id_array       output attribute list resolved here
1359  *
1360  * - Description:
1361  *     Resolve attribute id array as defined by the AVRCP specification.
1362  *
1363  * - Returns:
1364  *     The number of attributes filled in
1365  *
1366  ***************************************************************************/
fill_attribute_id_array(uint8_t cmd_attribute_number,btrc_media_attr_t * cmd_attribute_id_array,size_t out_array_size,btrc_media_attr_t * out_attribute_id_array)1367 static uint8_t fill_attribute_id_array(
1368     uint8_t cmd_attribute_number, btrc_media_attr_t* cmd_attribute_id_array,
1369     size_t out_array_size, btrc_media_attr_t* out_attribute_id_array) {
1370   /* Reset attribute array */
1371   memset(out_attribute_id_array, 0, out_array_size);
1372   /* Default case for cmd_attribute_number == 0xFF, No attribute */
1373   uint8_t out_attribute_number = 0;
1374   if (cmd_attribute_number == 0) {
1375     /* All attributes */
1376     out_attribute_number = out_array_size < AVRC_MAX_NUM_MEDIA_ATTR_ID
1377                                ? out_array_size
1378                                : AVRC_MAX_NUM_MEDIA_ATTR_ID;
1379     for (int i = 0; i < out_attribute_number; i++) {
1380       out_attribute_id_array[i] = (btrc_media_attr_t)(i + 1);
1381     }
1382   } else if (cmd_attribute_number != 0xFF) {
1383     /* Attribute List */
1384     out_attribute_number = 0;
1385     int filled_id_count = 0;
1386     for (int i = 0; (i < cmd_attribute_number) &&
1387                     (out_attribute_number < out_array_size) &&
1388                     (out_attribute_number < AVRC_MAX_NUM_MEDIA_ATTR_ID);
1389          i++) {
1390       /* Fill only valid entries */
1391       if (AVRC_IS_VALID_MEDIA_ATTRIBUTE(cmd_attribute_id_array[i])) {
1392         /* Skip the duplicate entries */
1393         for (filled_id_count = 0; filled_id_count < out_attribute_number;
1394              filled_id_count++) {
1395           if (out_attribute_id_array[filled_id_count] ==
1396               cmd_attribute_id_array[i])
1397             break;
1398         }
1399         /* New ID */
1400         if (filled_id_count == out_attribute_number) {
1401           out_attribute_id_array[out_attribute_number] =
1402               (btrc_media_attr_t)cmd_attribute_id_array[i];
1403           out_attribute_number++;
1404         }
1405       }
1406     }
1407   }
1408   return out_attribute_number;
1409 }
1410 
1411 /*******************************************************************************
1412  *
1413  * Function         btif_rc_upstreams_evt
1414  *
1415  * Description      Executes AVRC UPSTREAMS events in btif context.
1416  *
1417  * Returns          void
1418  *
1419  ******************************************************************************/
btif_rc_upstreams_evt(uint16_t event,tAVRC_COMMAND * pavrc_cmd,uint8_t ctype,uint8_t label,btif_rc_device_cb_t * p_dev)1420 static void btif_rc_upstreams_evt(uint16_t event, tAVRC_COMMAND* pavrc_cmd,
1421                                   uint8_t ctype, uint8_t label,
1422                                   btif_rc_device_cb_t* p_dev) {
1423   BTIF_TRACE_EVENT("%s: pdu: %s handle: 0x%x ctype: %x label: %x event ID: %x",
1424                    __func__, dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle,
1425                    ctype, label, pavrc_cmd->reg_notif.event_id);
1426 
1427   switch (event) {
1428     case AVRC_PDU_GET_PLAY_STATUS: {
1429       fill_pdu_queue(IDX_GET_PLAY_STATUS_RSP, ctype, label, true, p_dev);
1430       HAL_CBACK(bt_rc_callbacks, get_play_status_cb, p_dev->rc_addr);
1431     } break;
1432     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1433     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1434     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1435     case AVRC_PDU_SET_PLAYER_APP_VALUE:
1436     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1437     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT: {
1438       /* TODO: Add support for Application Settings */
1439       send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1440                            AVRC_STS_BAD_CMD, pavrc_cmd->cmd.opcode);
1441     } break;
1442     case AVRC_PDU_GET_ELEMENT_ATTR: {
1443       btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1444       uint8_t num_attr = fill_attribute_id_array(
1445           pavrc_cmd->get_elem_attrs.num_attr,
1446           (btrc_media_attr_t*)pavrc_cmd->get_elem_attrs.attrs,
1447           BTRC_MAX_ELEM_ATTR_SIZE, element_attrs);
1448       if (num_attr == 0) {
1449         BTIF_TRACE_ERROR(
1450             "%s: No valid attributes requested in GET_ELEMENT_ATTRIBUTES",
1451             __func__);
1452         send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1453                              AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode);
1454         return;
1455       }
1456       fill_pdu_queue(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, true, p_dev);
1457       HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs,
1458                 p_dev->rc_addr);
1459     } break;
1460     case AVRC_PDU_REGISTER_NOTIFICATION: {
1461       if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1462           pavrc_cmd->reg_notif.param == 0) {
1463         BTIF_TRACE_WARNING(
1464             "%s: Device registering position changed with illegal param 0.",
1465             __func__);
1466         send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1467                              AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode);
1468         /* de-register this notification for a rejected response */
1469         p_dev->rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = false;
1470         return;
1471       }
1472       HAL_CBACK(bt_rc_callbacks, register_notification_cb,
1473                 (btrc_event_id_t)pavrc_cmd->reg_notif.event_id,
1474                 pavrc_cmd->reg_notif.param, p_dev->rc_addr);
1475     } break;
1476     case AVRC_PDU_INFORM_DISPLAY_CHARSET: {
1477       tAVRC_RESPONSE avrc_rsp;
1478       BTIF_TRACE_EVENT("%s: AVRC_PDU_INFORM_DISPLAY_CHARSET", __func__);
1479       if (p_dev->rc_connected) {
1480         memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1481         avrc_rsp.inform_charset.opcode =
1482             opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1483         avrc_rsp.inform_charset.pdu = AVRC_PDU_INFORM_DISPLAY_CHARSET;
1484         avrc_rsp.inform_charset.status = AVRC_STS_NO_ERROR;
1485         send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp);
1486       }
1487     } break;
1488 
1489     case AVRC_PDU_GET_FOLDER_ITEMS: {
1490       uint32_t attr_ids[BTRC_MAX_ELEM_ATTR_SIZE];
1491       uint8_t num_attr;
1492       num_attr = pavrc_cmd->get_items.attr_count;
1493 
1494       BTIF_TRACE_EVENT(
1495           "%s: AVRC_PDU_GET_FOLDER_ITEMS num_attr: %d, start_item [%d] \
1496                 end_item [%d]",
1497           __func__, num_attr, pavrc_cmd->get_items.start_item,
1498           pavrc_cmd->get_items.end_item);
1499 
1500       /* num_attr requested:
1501        *     0x00: All attributes requested
1502        *     0xFF: No Attributes requested
1503        *     0x01 to 0x07: Specified number of attributes
1504        */
1505       if ((num_attr != 0xFF && num_attr > BTRC_MAX_ELEM_ATTR_SIZE)) {
1506         send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1507                              AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode);
1508         return;
1509       }
1510 
1511       /* Except num_attr is None(0xff) / All(0x00), request follows with an
1512        * Attribute List */
1513       if ((num_attr != 0xFF) && (num_attr != 0x00)) {
1514         memcpy(attr_ids, pavrc_cmd->get_items.p_attr_list,
1515                sizeof(uint32_t) * num_attr);
1516       }
1517 
1518       fill_pdu_queue(IDX_GET_FOLDER_ITEMS_RSP, ctype, label, true, p_dev);
1519       HAL_CBACK(bt_rc_callbacks, get_folder_items_cb,
1520                 pavrc_cmd->get_items.scope, pavrc_cmd->get_items.start_item,
1521                 pavrc_cmd->get_items.end_item, num_attr, attr_ids,
1522                 p_dev->rc_addr);
1523     } break;
1524 
1525     case AVRC_PDU_SET_ADDRESSED_PLAYER: {
1526       fill_pdu_queue(IDX_SET_ADDR_PLAYER_RSP, ctype, label, true, p_dev);
1527       HAL_CBACK(bt_rc_callbacks, set_addressed_player_cb,
1528                 pavrc_cmd->addr_player.player_id, p_dev->rc_addr);
1529     } break;
1530 
1531     case AVRC_PDU_SET_BROWSED_PLAYER: {
1532       fill_pdu_queue(IDX_SET_BROWSED_PLAYER_RSP, ctype, label, true, p_dev);
1533       HAL_CBACK(bt_rc_callbacks, set_browsed_player_cb,
1534                 pavrc_cmd->br_player.player_id, p_dev->rc_addr);
1535     } break;
1536 
1537     case AVRC_PDU_REQUEST_CONTINUATION_RSP: {
1538       BTIF_TRACE_EVENT("%s() REQUEST CONTINUATION: target_pdu: 0x%02d",
1539                        __func__, pavrc_cmd->continu.target_pdu);
1540       tAVRC_RESPONSE avrc_rsp;
1541       if (p_dev->rc_connected == TRUE) {
1542         memset(&(avrc_rsp.continu), 0, sizeof(tAVRC_NEXT_RSP));
1543         avrc_rsp.continu.opcode =
1544             opcode_from_pdu(AVRC_PDU_REQUEST_CONTINUATION_RSP);
1545         avrc_rsp.continu.pdu = AVRC_PDU_REQUEST_CONTINUATION_RSP;
1546         avrc_rsp.continu.status = AVRC_STS_NO_ERROR;
1547         avrc_rsp.continu.target_pdu = pavrc_cmd->continu.target_pdu;
1548         send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp);
1549       }
1550     } break;
1551 
1552     case AVRC_PDU_ABORT_CONTINUATION_RSP: {
1553       BTIF_TRACE_EVENT("%s() ABORT CONTINUATION: target_pdu: 0x%02d", __func__,
1554                        pavrc_cmd->abort.target_pdu);
1555       tAVRC_RESPONSE avrc_rsp;
1556       if (p_dev->rc_connected == TRUE) {
1557         memset(&(avrc_rsp.abort), 0, sizeof(tAVRC_NEXT_RSP));
1558         avrc_rsp.abort.opcode =
1559             opcode_from_pdu(AVRC_PDU_ABORT_CONTINUATION_RSP);
1560         avrc_rsp.abort.pdu = AVRC_PDU_ABORT_CONTINUATION_RSP;
1561         avrc_rsp.abort.status = AVRC_STS_NO_ERROR;
1562         avrc_rsp.abort.target_pdu = pavrc_cmd->continu.target_pdu;
1563         send_metamsg_rsp(p_dev, -1, label, ctype, &avrc_rsp);
1564       }
1565     } break;
1566 
1567     case AVRC_PDU_CHANGE_PATH: {
1568       fill_pdu_queue(IDX_CHG_PATH_RSP, ctype, label, true, p_dev);
1569       HAL_CBACK(bt_rc_callbacks, change_path_cb, pavrc_cmd->chg_path.direction,
1570                 pavrc_cmd->chg_path.folder_uid, p_dev->rc_addr);
1571     } break;
1572 
1573     case AVRC_PDU_SEARCH: {
1574       fill_pdu_queue(IDX_SEARCH_RSP, ctype, label, true, p_dev);
1575       HAL_CBACK(bt_rc_callbacks, search_cb, pavrc_cmd->search.string.charset_id,
1576                 pavrc_cmd->search.string.str_len,
1577                 pavrc_cmd->search.string.p_str, p_dev->rc_addr);
1578     } break;
1579 
1580     case AVRC_PDU_GET_ITEM_ATTRIBUTES: {
1581       btrc_media_attr_t item_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1582       uint8_t num_attr = fill_attribute_id_array(
1583           pavrc_cmd->get_attrs.attr_count,
1584           (btrc_media_attr_t*)pavrc_cmd->get_attrs.p_attr_list,
1585           BTRC_MAX_ELEM_ATTR_SIZE, item_attrs);
1586       if (num_attr == 0) {
1587         BTIF_TRACE_ERROR(
1588             "%s: No valid attributes requested in GET_ITEM_ATTRIBUTES",
1589             __func__);
1590         send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1591                              AVRC_STS_BAD_PARAM, pavrc_cmd->cmd.opcode);
1592         return;
1593       }
1594       fill_pdu_queue(IDX_GET_ITEM_ATTR_RSP, ctype, label, true, p_dev);
1595       BTIF_TRACE_DEBUG("%s: GET_ITEM_ATTRIBUTES: num_attr: %d", __func__,
1596                        num_attr);
1597       HAL_CBACK(bt_rc_callbacks, get_item_attr_cb, pavrc_cmd->get_attrs.scope,
1598                 pavrc_cmd->get_attrs.uid, pavrc_cmd->get_attrs.uid_counter,
1599                 num_attr, item_attrs, p_dev->rc_addr);
1600     } break;
1601 
1602     case AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS: {
1603       fill_pdu_queue(IDX_GET_TOTAL_NUM_OF_ITEMS_RSP, ctype, label, true, p_dev);
1604       HAL_CBACK(bt_rc_callbacks, get_total_num_of_items_cb,
1605                 pavrc_cmd->get_num_of_items.scope, p_dev->rc_addr);
1606     } break;
1607 
1608     case AVRC_PDU_ADD_TO_NOW_PLAYING: {
1609       fill_pdu_queue(IDX_ADD_TO_NOW_PLAYING_RSP, ctype, label, true, p_dev);
1610       HAL_CBACK(bt_rc_callbacks, add_to_now_playing_cb,
1611                 pavrc_cmd->add_to_play.scope, pavrc_cmd->add_to_play.uid,
1612                 pavrc_cmd->add_to_play.uid_counter, p_dev->rc_addr);
1613     } break;
1614 
1615     case AVRC_PDU_PLAY_ITEM: {
1616       fill_pdu_queue(IDX_PLAY_ITEM_RSP, ctype, label, true, p_dev);
1617       HAL_CBACK(bt_rc_callbacks, play_item_cb, pavrc_cmd->play_item.scope,
1618                 pavrc_cmd->play_item.uid_counter, pavrc_cmd->play_item.uid,
1619                 p_dev->rc_addr);
1620     } break;
1621 
1622     default: {
1623       send_reject_response(p_dev->rc_handle, label, pavrc_cmd->pdu,
1624                            AVRC_STS_BAD_CMD, pavrc_cmd->cmd.opcode);
1625       return;
1626     } break;
1627   }
1628 }
1629 
1630 /*******************************************************************************
1631  *
1632  * Function         btif_rc_ctrl_upstreams_rsp_cmd
1633  *
1634  * Description      Executes AVRC UPSTREAMS response events in btif context.
1635  *
1636  * Returns          void
1637  *
1638  ******************************************************************************/
btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event,tAVRC_COMMAND * pavrc_cmd,uint8_t label,btif_rc_device_cb_t * p_dev)1639 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event,
1640                                            tAVRC_COMMAND* pavrc_cmd,
1641                                            uint8_t label,
1642                                            btif_rc_device_cb_t* p_dev) {
1643   BTIF_TRACE_DEBUG("%s: pdu: %s: handle: 0x%x", __func__,
1644                    dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle);
1645   switch (event) {
1646     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1647       do_in_jni_thread(
1648           FROM_HERE,
1649           base::Bind(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr,
1650                      pavrc_cmd->volume.volume, label));
1651       break;
1652     case AVRC_PDU_REGISTER_NOTIFICATION:
1653       if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) {
1654         do_in_jni_thread(
1655             FROM_HERE,
1656             base::Bind(bt_rc_ctrl_callbacks->registernotification_absvol_cb,
1657                        p_dev->rc_addr, label));
1658       }
1659       break;
1660   }
1661 }
1662 
1663 /*******************************************************************************
1664  *
1665  * Function         btif_rc_upstreams_rsp_evt
1666  *
1667  * Description      Executes AVRC UPSTREAMS response events in btif context.
1668  *
1669  * Returns          void
1670  *
1671  ******************************************************************************/
btif_rc_upstreams_rsp_evt(uint16_t event,tAVRC_RESPONSE * pavrc_resp,uint8_t ctype,uint8_t label,btif_rc_device_cb_t * p_dev)1672 static void btif_rc_upstreams_rsp_evt(uint16_t event,
1673                                       tAVRC_RESPONSE* pavrc_resp, uint8_t ctype,
1674                                       uint8_t label,
1675                                       btif_rc_device_cb_t* p_dev) {
1676   BTIF_TRACE_EVENT("%s: pdu: %s: handle: 0x%x ctype: %x label: %x", __func__,
1677                    dump_rc_pdu(pavrc_resp->pdu), p_dev->rc_handle, ctype,
1678                    label);
1679 
1680   switch (event) {
1681     case AVRC_PDU_REGISTER_NOTIFICATION: {
1682       if (AVRC_RSP_CHANGED == ctype)
1683         p_dev->rc_volume = pavrc_resp->reg_notif.param.volume;
1684       HAL_CBACK(bt_rc_callbacks, volume_change_cb,
1685                 pavrc_resp->reg_notif.param.volume, ctype, p_dev->rc_addr);
1686     } break;
1687 
1688     case AVRC_PDU_SET_ABSOLUTE_VOLUME: {
1689       BTIF_TRACE_DEBUG(
1690           "%s: Set absolute volume change event received: volume: %d, ctype: "
1691           "%d",
1692           __func__, pavrc_resp->volume.volume, ctype);
1693       if (AVRC_RSP_ACCEPT == ctype)
1694         p_dev->rc_volume = pavrc_resp->volume.volume;
1695       HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->volume.volume,
1696                 ctype, p_dev->rc_addr);
1697     } break;
1698 
1699     default:
1700       return;
1701   }
1702 }
1703 
1704 /*******************************************************************************
1705  *  AVRCP API Functions
1706  ******************************************************************************/
1707 
1708 /*******************************************************************************
1709  *
1710  * Function         init
1711  *
1712  * Description      Initializes the AVRC interface
1713  *
1714  * Returns          bt_status_t
1715  *
1716  ******************************************************************************/
init(btrc_callbacks_t * callbacks)1717 static bt_status_t init(btrc_callbacks_t* callbacks) {
1718   BTIF_TRACE_EVENT("%s: ", __func__);
1719   bt_status_t result = BT_STATUS_SUCCESS;
1720 
1721   if (bt_rc_callbacks) return BT_STATUS_DONE;
1722 
1723   bt_rc_callbacks = callbacks;
1724   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1725     memset(&btif_rc_cb.rc_multi_cb[idx], 0,
1726            sizeof(btif_rc_cb.rc_multi_cb[idx]));
1727     btif_rc_cb.rc_multi_cb[idx].rc_vol_label = MAX_LABEL;
1728     btif_rc_cb.rc_multi_cb[idx].rc_volume = MAX_VOLUME;
1729     btif_rc_cb.rc_multi_cb[idx].rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
1730   }
1731   lbl_init();
1732 
1733   return result;
1734 }
1735 
1736 /*******************************************************************************
1737  *
1738  * Function         init_ctrl
1739  *
1740  * Description      Initializes the AVRC interface
1741  *
1742  * Returns          bt_status_t
1743  *
1744  ******************************************************************************/
init_ctrl(btrc_ctrl_callbacks_t * callbacks)1745 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) {
1746   BTIF_TRACE_EVENT("%s: ", __func__);
1747   bt_status_t result = BT_STATUS_SUCCESS;
1748 
1749   if (bt_rc_ctrl_callbacks) return BT_STATUS_DONE;
1750 
1751   bt_rc_ctrl_callbacks = callbacks;
1752   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1753     memset(&btif_rc_cb.rc_multi_cb[idx], 0,
1754            sizeof(btif_rc_cb.rc_multi_cb[idx]));
1755     btif_rc_cb.rc_multi_cb[idx].rc_vol_label = MAX_LABEL;
1756     btif_rc_cb.rc_multi_cb[idx].rc_volume = MAX_VOLUME;
1757   }
1758   lbl_init();
1759 
1760   return result;
1761 }
1762 
rc_ctrl_procedure_complete(btif_rc_device_cb_t * p_dev)1763 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev) {
1764   if (p_dev == NULL) {
1765     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
1766     return;
1767   }
1768 
1769   if (p_dev->rc_procedure_complete) {
1770     return;
1771   }
1772   p_dev->rc_procedure_complete = true;
1773   uint32_t attr_list[] = {
1774       AVRC_MEDIA_ATTR_ID_TITLE,       AVRC_MEDIA_ATTR_ID_ARTIST,
1775       AVRC_MEDIA_ATTR_ID_ALBUM,       AVRC_MEDIA_ATTR_ID_TRACK_NUM,
1776       AVRC_MEDIA_ATTR_ID_NUM_TRACKS,  AVRC_MEDIA_ATTR_ID_GENRE,
1777       AVRC_MEDIA_ATTR_ID_PLAYING_TIME};
1778   get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev);
1779 }
1780 
1781 /***************************************************************************
1782  *
1783  * Function         get_play_status_rsp
1784  *
1785  * Description      Returns the current play status.
1786  *                      This method is called in response to
1787  *                      GetPlayStatus request.
1788  *
1789  * Returns          bt_status_t
1790  *
1791  **************************************************************************/
get_play_status_rsp(const RawAddress & bd_addr,btrc_play_status_t play_status,uint32_t song_len,uint32_t song_pos)1792 static bt_status_t get_play_status_rsp(const RawAddress& bd_addr,
1793                                        btrc_play_status_t play_status,
1794                                        uint32_t song_len, uint32_t song_pos) {
1795   tAVRC_RESPONSE avrc_rsp;
1796   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
1797 
1798   BTIF_TRACE_DEBUG("%s: song len %d song pos %d", __func__, song_len, song_pos);
1799   CHECK_RC_CONNECTED(p_dev);
1800 
1801   memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1802 
1803   avrc_rsp.get_play_status.song_len = song_len;
1804   avrc_rsp.get_play_status.song_pos = song_pos;
1805   avrc_rsp.get_play_status.play_status = play_status;
1806 
1807   avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1808   avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1809   avrc_rsp.get_play_status.status =
1810       ((play_status != BTRC_PLAYSTATE_ERROR) ? AVRC_STS_NO_ERROR
1811                                              : AVRC_STS_BAD_PARAM);
1812 
1813   /* Send the response */
1814   send_metamsg_rsp(p_dev, IDX_GET_PLAY_STATUS_RSP,
1815                    p_dev->rc_pdu_info[IDX_GET_PLAY_STATUS_RSP].label,
1816                    p_dev->rc_pdu_info[IDX_GET_PLAY_STATUS_RSP].ctype,
1817                    &avrc_rsp);
1818 
1819   return BT_STATUS_SUCCESS;
1820 }
1821 
1822 /***************************************************************************
1823  *
1824  * Function         get_element_attr_rsp
1825  *
1826  * Description      Returns the current songs' element attributes
1827  *                      in text.
1828  *
1829  * Returns          bt_status_t
1830  *
1831  **************************************************************************/
get_element_attr_rsp(const RawAddress & bd_addr,uint8_t num_attr,btrc_element_attr_val_t * p_attrs)1832 static bt_status_t get_element_attr_rsp(const RawAddress& bd_addr,
1833                                         uint8_t num_attr,
1834                                         btrc_element_attr_val_t* p_attrs) {
1835   tAVRC_RESPONSE avrc_rsp;
1836   uint32_t i;
1837   tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1838   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
1839 
1840   BTIF_TRACE_DEBUG("%s", __func__);
1841   CHECK_RC_CONNECTED(p_dev);
1842 
1843   memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1844 
1845   if (num_attr == 0) {
1846     avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1847   } else {
1848     for (i = 0; i < num_attr; i++) {
1849       element_attrs[i].attr_id = p_attrs[i].attr_id;
1850       element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1851       element_attrs[i].name.str_len = (uint16_t)strlen((char*)p_attrs[i].text);
1852       element_attrs[i].name.p_str = p_attrs[i].text;
1853       BTIF_TRACE_DEBUG(
1854           "%s: attr_id: 0x%x, charset_id: 0x%x, str_len: %d, str: %s", __func__,
1855           (unsigned int)element_attrs[i].attr_id,
1856           element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1857           element_attrs[i].name.p_str);
1858     }
1859     avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1860   }
1861   avrc_rsp.get_attrs.num_attrs = num_attr;
1862   avrc_rsp.get_attrs.p_attrs = element_attrs;
1863   avrc_rsp.get_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1864   avrc_rsp.get_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1865 
1866   /* Send the response */
1867   send_metamsg_rsp(p_dev, IDX_GET_ELEMENT_ATTR_RSP,
1868                    p_dev->rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP].label,
1869                    p_dev->rc_pdu_info[IDX_GET_ELEMENT_ATTR_RSP].ctype,
1870                    &avrc_rsp);
1871 
1872   return BT_STATUS_SUCCESS;
1873 }
1874 
1875 /***************************************************************************
1876  *
1877  * Function         register_notification_rsp
1878  *
1879  * Description      Response to the register notification request.
1880  *
1881  * Returns          bt_status_t
1882  *
1883  **************************************************************************/
register_notification_rsp(btrc_event_id_t event_id,btrc_notification_type_t type,btrc_register_notification_t * p_param)1884 static bt_status_t register_notification_rsp(
1885     btrc_event_id_t event_id, btrc_notification_type_t type,
1886     btrc_register_notification_t* p_param) {
1887   tAVRC_RESPONSE avrc_rsp;
1888   BTIF_TRACE_EVENT("%s: event_id: %s", __func__,
1889                    dump_rc_notification_event_id(event_id));
1890   std::unique_lock<std::mutex> lock(btif_rc_cb.lock);
1891 
1892   memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1893 
1894   avrc_rsp.reg_notif.event_id = event_id;
1895   avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1896   avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1897   avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1898 
1899   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1900     memset(&(avrc_rsp.reg_notif.param), 0, sizeof(tAVRC_NOTIF_RSP_PARAM));
1901 
1902     if (!(btif_rc_cb.rc_multi_cb[idx].rc_connected)) {
1903       BTIF_TRACE_ERROR("%s: Avrcp device is not connected, handle: 0x%x",
1904                        __func__, btif_rc_cb.rc_multi_cb[idx].rc_handle);
1905       continue;
1906     }
1907 
1908     if (!btif_rc_cb.rc_multi_cb[idx].rc_notif[event_id - 1].bNotify) {
1909       BTIF_TRACE_WARNING(
1910           "%s: Avrcp Event id is not registered: event_id: %x, handle: 0x%x",
1911           __func__, event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle);
1912       continue;
1913     }
1914 
1915     BTIF_TRACE_DEBUG(
1916         "%s: Avrcp Event id is registered: event_id: %x handle: 0x%x", __func__,
1917         event_id, btif_rc_cb.rc_multi_cb[idx].rc_handle);
1918 
1919     switch (event_id) {
1920       case BTRC_EVT_PLAY_STATUS_CHANGED:
1921         avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1922         if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING)
1923           btif_av_clear_remote_suspend_flag();
1924         break;
1925       case BTRC_EVT_TRACK_CHANGE:
1926         memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track),
1927                sizeof(btrc_uid_t));
1928         break;
1929       case BTRC_EVT_PLAY_POS_CHANGED:
1930         avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1931         break;
1932       case BTRC_EVT_AVAL_PLAYER_CHANGE:
1933         break;
1934       case BTRC_EVT_ADDR_PLAYER_CHANGE:
1935         avrc_rsp.reg_notif.param.addr_player.player_id =
1936             p_param->addr_player_changed.player_id;
1937         avrc_rsp.reg_notif.param.addr_player.uid_counter =
1938             p_param->addr_player_changed.uid_counter;
1939         break;
1940       case BTRC_EVT_UIDS_CHANGED:
1941         avrc_rsp.reg_notif.param.uid_counter =
1942             p_param->uids_changed.uid_counter;
1943         break;
1944       case BTRC_EVT_NOW_PLAYING_CONTENT_CHANGED:
1945         break;
1946 
1947       default:
1948         BTIF_TRACE_WARNING("%s: Unhandled event ID: 0x%x", __func__, event_id);
1949         return BT_STATUS_UNHANDLED;
1950     }
1951 
1952     /* Send the response. */
1953     send_metamsg_rsp(
1954         &btif_rc_cb.rc_multi_cb[idx], -1,
1955         btif_rc_cb.rc_multi_cb[idx].rc_notif[event_id - 1].label,
1956         ((type == BTRC_NOTIFICATION_TYPE_INTERIM) ? AVRC_CMD_NOTIF
1957                                                   : AVRC_RSP_CHANGED),
1958         &avrc_rsp);
1959   }
1960   return BT_STATUS_SUCCESS;
1961 }
1962 
1963 /***************************************************************************
1964  *
1965  * Function         get_folder_items_list_rsp
1966  *
1967  * Description      Returns the list of media items in current folder along with
1968  *                  requested attributes. This is called in response to
1969  *                  GetFolderItems request.
1970  *
1971  * Returns          bt_status_t
1972  *                      BT_STATUS_NOT_READY - when RC is not connected.
1973  *                      BT_STATUS_SUCCESS   - always if RC is connected
1974  *                      BT_STATUS_UNHANDLED - when rsp is not pending for
1975  *                                            get_folder_items_list PDU
1976  *
1977  **************************************************************************/
get_folder_items_list_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint16_t uid_counter,uint8_t num_items,btrc_folder_items_t * p_items)1978 static bt_status_t get_folder_items_list_rsp(const RawAddress& bd_addr,
1979                                              btrc_status_t rsp_status,
1980                                              uint16_t uid_counter,
1981                                              uint8_t num_items,
1982                                              btrc_folder_items_t* p_items) {
1983   tAVRC_RESPONSE avrc_rsp;
1984   tAVRC_ITEM item;
1985   tBTA_AV_CODE code = 0, ctype = 0;
1986   BT_HDR* p_msg = NULL;
1987   int item_cnt;
1988   tAVRC_STS status = AVRC_STS_NO_ERROR;
1989   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
1990   btrc_folder_items_t* cur_item = NULL;
1991 
1992   BTIF_TRACE_DEBUG("%s: uid_counter %d num_items %d", __func__, uid_counter,
1993                    num_items);
1994   CHECK_RC_CONNECTED(p_dev);
1995 
1996   /* check if rsp to previous cmd was completed */
1997   if (!p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].is_rsp_pending) {
1998     BTIF_TRACE_WARNING("%s: Not sending response as no PDU was registered",
1999                        __func__);
2000     return BT_STATUS_UNHANDLED;
2001   }
2002 
2003   memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
2004   memset(&item, 0, sizeof(tAVRC_ITEM));
2005 
2006   avrc_rsp.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS;
2007   avrc_rsp.get_items.opcode = opcode_from_pdu(AVRC_PDU_GET_FOLDER_ITEMS);
2008   avrc_rsp.get_items.status = status_code_map[rsp_status];
2009 
2010   if (avrc_rsp.get_items.status != AVRC_STS_NO_ERROR) {
2011     BTIF_TRACE_WARNING(
2012         "%s: Error in parsing the received getfolderitems cmd. status: 0x%02x",
2013         __func__, avrc_rsp.get_items.status);
2014     status = avrc_rsp.get_items.status;
2015   } else {
2016     avrc_rsp.get_items.uid_counter = uid_counter;
2017     avrc_rsp.get_items.item_count = 1;
2018 
2019     /* create single item and build response iteratively for all num_items */
2020     for (item_cnt = 0; item_cnt < num_items; item_cnt++) {
2021       cur_item = &p_items[item_cnt];
2022       item.item_type = p_items->item_type;
2023       /* build respective item based on item_type. All items should be of same
2024        * type within
2025        * a response */
2026       switch (p_items->item_type) {
2027         case AVRC_ITEM_PLAYER: {
2028           item.u.player.name.charset_id = cur_item->player.charset_id;
2029           memcpy(&(item.u.player.features), &(cur_item->player.features),
2030                  sizeof(cur_item->player.features));
2031           item.u.player.major_type = cur_item->player.major_type;
2032           item.u.player.sub_type = cur_item->player.sub_type;
2033           item.u.player.play_status = cur_item->player.play_status;
2034           item.u.player.player_id = cur_item->player.player_id;
2035           item.u.player.name.p_str = cur_item->player.name;
2036           item.u.player.name.str_len =
2037               (uint16_t)strlen((char*)(cur_item->player.name));
2038         } break;
2039 
2040         case AVRC_ITEM_FOLDER: {
2041           memcpy(item.u.folder.uid, cur_item->folder.uid, sizeof(tAVRC_UID));
2042           item.u.folder.type = cur_item->folder.type;
2043           item.u.folder.playable = cur_item->folder.playable;
2044           item.u.folder.name.charset_id = AVRC_CHARSET_ID_UTF8;
2045           item.u.folder.name.str_len = strlen((char*)cur_item->folder.name);
2046           item.u.folder.name.p_str = cur_item->folder.name;
2047         } break;
2048 
2049         case AVRC_ITEM_MEDIA: {
2050           tAVRC_ATTR_ENTRY attr_vals[BTRC_MAX_ELEM_ATTR_SIZE];
2051 
2052           memcpy(item.u.media.uid, cur_item->media.uid, sizeof(tAVRC_UID));
2053           item.u.media.type = cur_item->media.type;
2054           item.u.media.name.charset_id = cur_item->media.charset_id;
2055           item.u.media.name.str_len = strlen((char*)cur_item->media.name);
2056           item.u.media.name.p_str = cur_item->media.name;
2057           item.u.media.attr_count = cur_item->media.num_attrs;
2058 
2059           /* Handle attributes of given item */
2060           if (item.u.media.attr_count == 0) {
2061             item.u.media.p_attr_list = NULL;
2062           } else {
2063             memset(&attr_vals, 0,
2064                    sizeof(tAVRC_ATTR_ENTRY) * BTRC_MAX_ELEM_ATTR_SIZE);
2065             fill_avrc_attr_entry(attr_vals, item.u.media.attr_count,
2066                                  cur_item->media.p_attrs);
2067             item.u.media.p_attr_list = attr_vals;
2068           }
2069         } break;
2070 
2071         default: {
2072           BTIF_TRACE_ERROR("%s: Unknown item_type: %d. Internal Error",
2073                            __func__, p_items->item_type);
2074           status = AVRC_STS_INTERNAL_ERR;
2075         } break;
2076       }
2077 
2078       avrc_rsp.get_items.p_item_list = &item;
2079 
2080       /* Add current item to buffer and build response if no error in item type
2081        */
2082       if (status != AVRC_STS_NO_ERROR) {
2083         /* Reject response due to error occured for unknown item_type, break the
2084          * loop */
2085         break;
2086       }
2087 
2088       int len_before = p_msg ? p_msg->len : 0;
2089       BTIF_TRACE_DEBUG("%s: item_cnt: %d len: %d", __func__, item_cnt,
2090                        len_before);
2091       status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
2092       BTIF_TRACE_DEBUG("%s: Build rsp status: %d len: %d", __func__, status,
2093                        (p_msg ? p_msg->len : 0));
2094       int len_after = p_msg ? p_msg->len : 0;
2095       if (status != AVRC_STS_NO_ERROR || len_before == len_after) {
2096         /* Error occured in build response or we ran out of buffer so break the
2097          * loop */
2098         break;
2099       }
2100     }
2101 
2102     /* setting the error status */
2103     avrc_rsp.get_items.status = status;
2104   }
2105 
2106   /* if packet built successfully, send the built items to BTA layer */
2107   if (status == AVRC_STS_NO_ERROR) {
2108     code = p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].ctype;
2109     ctype = get_rsp_type_code(avrc_rsp.get_items.status, code);
2110     BTA_AvMetaRsp(p_dev->rc_handle,
2111                   p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label, ctype,
2112                   p_msg);
2113   } else /* Error occured, send reject response */
2114   {
2115     BTIF_TRACE_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__,
2116                      avrc_rsp.rsp.status);
2117     send_reject_response(
2118         p_dev->rc_handle, p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label,
2119         avrc_rsp.pdu, avrc_rsp.get_items.status, avrc_rsp.get_items.opcode);
2120   }
2121 
2122   /* Reset values for current pdu. */
2123   p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].ctype = 0;
2124   p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].label = 0;
2125   p_dev->rc_pdu_info[IDX_GET_FOLDER_ITEMS_RSP].is_rsp_pending = false;
2126 
2127   return status == AVRC_STS_NO_ERROR ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
2128 }
2129 
2130 /***************************************************************************
2131  *
2132  * Function         set_addressed_player_rsp
2133  *
2134  * Description      Response to set the addressed player for specified media
2135  *                  player based on id in the media player list.
2136  *
2137  * Returns          bt_status_t
2138  *                      BT_STATUS_NOT_READY - when RC is not connected.
2139  *                      BT_STATUS_SUCCESS   - always if RC is connected
2140  *
2141  **************************************************************************/
set_addressed_player_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status)2142 static bt_status_t set_addressed_player_rsp(const RawAddress& bd_addr,
2143                                             btrc_status_t rsp_status) {
2144   tAVRC_RESPONSE avrc_rsp;
2145   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2146 
2147   BTIF_TRACE_DEBUG("%s", __func__);
2148   CHECK_RC_CONNECTED(p_dev);
2149 
2150   avrc_rsp.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER;
2151   avrc_rsp.addr_player.opcode = opcode_from_pdu(AVRC_PDU_SET_ADDRESSED_PLAYER);
2152   avrc_rsp.addr_player.status = status_code_map[rsp_status];
2153 
2154   /* Send the response. */
2155   send_metamsg_rsp(p_dev, IDX_SET_ADDR_PLAYER_RSP,
2156                    p_dev->rc_pdu_info[IDX_SET_ADDR_PLAYER_RSP].label,
2157                    p_dev->rc_pdu_info[IDX_SET_ADDR_PLAYER_RSP].ctype,
2158                    &avrc_rsp);
2159 
2160   return BT_STATUS_SUCCESS;
2161 }
2162 
2163 /***************************************************************************
2164  *
2165  * Function         set_browsed_player_rsp
2166  *
2167  * Description      Response to set the browsed player command which contains
2168  *                  current browsed path of the media player. By default,
2169  *                  current_path = root and folder_depth = 0 for
2170  *                  every set_browsed_player request.
2171  *
2172  * Returns          bt_status_t
2173  *                      BT_STATUS_NOT_READY - when RC is not connected.
2174  *                      BT_STATUS_SUCCESS   - if RC is connected and reponse
2175  *                                            sent successfully
2176  *                      BT_STATUS_UNHANDLED - when rsp is not pending for
2177  *                                            set_browsed_player PDU
2178  *
2179  **************************************************************************/
set_browsed_player_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint32_t num_items,uint16_t charset_id,uint8_t folder_depth,btrc_br_folder_name_t * p_folders)2180 static bt_status_t set_browsed_player_rsp(const RawAddress& bd_addr,
2181                                           btrc_status_t rsp_status,
2182                                           uint32_t num_items,
2183                                           uint16_t charset_id,
2184                                           uint8_t folder_depth,
2185                                           btrc_br_folder_name_t* p_folders) {
2186   tAVRC_RESPONSE avrc_rsp;
2187   tAVRC_NAME item;
2188   BT_HDR* p_msg = NULL;
2189   tBTA_AV_CODE code = 0;
2190   tBTA_AV_CODE ctype = 0;
2191   unsigned int item_cnt;
2192   tAVRC_STS status = AVRC_STS_NO_ERROR;
2193   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2194 
2195   CHECK_RC_CONNECTED(p_dev);
2196 
2197   memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
2198   memset(&item, 0, sizeof(tAVRC_NAME));
2199 
2200   avrc_rsp.br_player.status = status_code_map[rsp_status];
2201   avrc_rsp.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER;
2202   avrc_rsp.br_player.opcode = opcode_from_pdu(AVRC_PDU_SET_BROWSED_PLAYER);
2203 
2204   BTIF_TRACE_DEBUG("%s: rsp_status: 0x%02X avrc_rsp.br_player.status: 0x%02X",
2205                    __func__, rsp_status, avrc_rsp.br_player.status);
2206 
2207   /* check if rsp to previous cmd was completed */
2208   if (!p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].is_rsp_pending) {
2209     BTIF_TRACE_WARNING("%s: Not sending response as no PDU was registered",
2210                        __func__);
2211     return BT_STATUS_UNHANDLED;
2212   }
2213 
2214   if (AVRC_STS_NO_ERROR == avrc_rsp.get_items.status) {
2215     avrc_rsp.br_player.num_items = num_items;
2216     avrc_rsp.br_player.charset_id = charset_id;
2217     avrc_rsp.br_player.folder_depth = folder_depth;
2218     avrc_rsp.br_player.p_folders = (tAVRC_NAME*)p_folders;
2219 
2220     BTIF_TRACE_DEBUG("%s: folder_depth: 0x%02X num_items: %d", __func__,
2221                      folder_depth, num_items);
2222 
2223     if (folder_depth > 0) {
2224       /* Iteratively build response for all folders across folder depth upto
2225        * current path */
2226       avrc_rsp.br_player.folder_depth = 1;
2227       for (item_cnt = 0; item_cnt < folder_depth; item_cnt++) {
2228         BTIF_TRACE_DEBUG("%s: iteration: %d", __func__, item_cnt);
2229         item.str_len = p_folders[item_cnt].str_len;
2230         item.p_str = p_folders[item_cnt].p_str;
2231         avrc_rsp.br_player.p_folders = &item;
2232 
2233         /* Add current item to buffer and build response */
2234         status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
2235         if (AVRC_STS_NO_ERROR != status) {
2236           BTIF_TRACE_WARNING("%s: Build rsp status: %d", __func__, status);
2237           /* if the build fails, it is likely that we ran out of buffer. so if
2238         * we have
2239         * some items to send, reset this error to no error for sending what we
2240         * have */
2241           if (item_cnt > 0) status = AVRC_STS_NO_ERROR;
2242 
2243           /* Error occured in build response so break the loop */
2244           break;
2245         }
2246       }
2247     } else /* current path is root folder, no folders navigated yet */
2248     {
2249       status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
2250     }
2251 
2252     /* setting the error status */
2253     avrc_rsp.br_player.status = status;
2254   } else /* error received from above layer */
2255   {
2256     BTIF_TRACE_WARNING(
2257         "%s: Error in parsing the received setbrowsed command. status: 0x%02x",
2258         __func__, avrc_rsp.br_player.status);
2259     status = avrc_rsp.br_player.status;
2260   }
2261 
2262   /* if packet built successfully, send the built items to BTA layer */
2263   if (status == AVRC_STS_NO_ERROR) {
2264     code = p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].ctype;
2265     ctype = get_rsp_type_code(avrc_rsp.br_player.status, code);
2266     BTA_AvMetaRsp(p_dev->rc_handle,
2267                   p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label, ctype,
2268                   p_msg);
2269   } else /* Error occured, send reject response */
2270   {
2271     BTIF_TRACE_ERROR("%s: Error status: 0x%02X. Sending reject rsp", __func__,
2272                      avrc_rsp.br_player.status);
2273     send_reject_response(
2274         p_dev->rc_handle, p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label,
2275         avrc_rsp.pdu, avrc_rsp.br_player.status, avrc_rsp.get_items.opcode);
2276   }
2277 
2278   /* Reset values for set_browsed_player pdu.*/
2279   p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].ctype = 0;
2280   p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].label = 0;
2281   p_dev->rc_pdu_info[IDX_SET_BROWSED_PLAYER_RSP].is_rsp_pending = false;
2282 
2283   return status == AVRC_STS_NO_ERROR ? BT_STATUS_SUCCESS : BT_STATUS_FAIL;
2284 }
2285 
2286 /*******************************************************************************
2287  *
2288  * Function         change_path_rsp
2289  *
2290  * Description      Response to the change path command which
2291  *                  contains number of items in the changed path.
2292  *
2293  * Returns          bt_status_t
2294  *                      BT_STATUS_NOT_READY - when RC is not connected.
2295  *                      BT_STATUS_SUCCESS   - always if RC is connected
2296  *
2297  **************************************************************************/
change_path_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint32_t num_items)2298 static bt_status_t change_path_rsp(const RawAddress& bd_addr,
2299                                    btrc_status_t rsp_status,
2300                                    uint32_t num_items) {
2301   tAVRC_RESPONSE avrc_rsp;
2302   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2303 
2304   BTIF_TRACE_DEBUG("%s", __func__);
2305   CHECK_RC_CONNECTED(p_dev);
2306 
2307   avrc_rsp.chg_path.pdu = AVRC_PDU_CHANGE_PATH;
2308   avrc_rsp.chg_path.opcode = opcode_from_pdu(AVRC_PDU_CHANGE_PATH);
2309   avrc_rsp.chg_path.num_items = num_items;
2310   avrc_rsp.chg_path.status = status_code_map[rsp_status];
2311 
2312   /* Send the response. */
2313   send_metamsg_rsp(p_dev, IDX_CHG_PATH_RSP,
2314                    p_dev->rc_pdu_info[IDX_CHG_PATH_RSP].label,
2315                    p_dev->rc_pdu_info[IDX_CHG_PATH_RSP].ctype, &avrc_rsp);
2316 
2317   return BT_STATUS_SUCCESS;
2318 }
2319 
2320 /***************************************************************************
2321  *
2322  * Function         search_rsp
2323  *
2324  * Description      Response to search a string from media content command.
2325  *
2326  * Returns          bt_status_t
2327  *                      BT_STATUS_NOT_READY - when RC is not connected.
2328  *                      BT_STATUS_SUCCESS   - always if RC is connected
2329  *
2330  **************************************************************************/
search_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint32_t uid_counter,uint32_t num_items)2331 static bt_status_t search_rsp(const RawAddress& bd_addr,
2332                               btrc_status_t rsp_status, uint32_t uid_counter,
2333                               uint32_t num_items) {
2334   tAVRC_RESPONSE avrc_rsp;
2335   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2336 
2337   BTIF_TRACE_DEBUG("%s", __func__);
2338   CHECK_RC_CONNECTED(p_dev);
2339 
2340   avrc_rsp.search.pdu = AVRC_PDU_SEARCH;
2341   avrc_rsp.search.opcode = opcode_from_pdu(AVRC_PDU_SEARCH);
2342   avrc_rsp.search.num_items = num_items;
2343   avrc_rsp.search.uid_counter = uid_counter;
2344   avrc_rsp.search.status = status_code_map[rsp_status];
2345 
2346   /* Send the response. */
2347   send_metamsg_rsp(p_dev, IDX_SEARCH_RSP,
2348                    p_dev->rc_pdu_info[IDX_SEARCH_RSP].label,
2349                    p_dev->rc_pdu_info[IDX_SEARCH_RSP].ctype, &avrc_rsp);
2350 
2351   return BT_STATUS_SUCCESS;
2352 }
2353 /***************************************************************************
2354  *
2355  * Function         get_item_attr_rsp
2356  *
2357  * Description      Response to the get item's attributes command which
2358  *                  contains number of attributes and values list in text.
2359  *
2360  * Returns          bt_status_t
2361  *                      BT_STATUS_NOT_READY - when RC is not connected.
2362  *                      BT_STATUS_SUCCESS   - always if RC is connected
2363  *
2364  **************************************************************************/
get_item_attr_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint8_t num_attr,btrc_element_attr_val_t * p_attrs)2365 static bt_status_t get_item_attr_rsp(const RawAddress& bd_addr,
2366                                      btrc_status_t rsp_status, uint8_t num_attr,
2367                                      btrc_element_attr_val_t* p_attrs) {
2368   tAVRC_RESPONSE avrc_rsp;
2369   tAVRC_ATTR_ENTRY item_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
2370   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2371 
2372   BTIF_TRACE_DEBUG("%s", __func__);
2373   CHECK_RC_CONNECTED(p_dev);
2374 
2375   memset(item_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
2376 
2377   avrc_rsp.get_attrs.status = status_code_map[rsp_status];
2378   if (rsp_status == BTRC_STS_NO_ERROR) {
2379     fill_avrc_attr_entry(item_attrs, num_attr, p_attrs);
2380   }
2381 
2382   avrc_rsp.get_attrs.num_attrs = num_attr;
2383   avrc_rsp.get_attrs.p_attrs = item_attrs;
2384   avrc_rsp.get_attrs.pdu = AVRC_PDU_GET_ITEM_ATTRIBUTES;
2385   avrc_rsp.get_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ITEM_ATTRIBUTES);
2386 
2387   /* Send the response. */
2388   send_metamsg_rsp(p_dev, IDX_GET_ITEM_ATTR_RSP,
2389                    p_dev->rc_pdu_info[IDX_GET_ITEM_ATTR_RSP].label,
2390                    p_dev->rc_pdu_info[IDX_GET_ITEM_ATTR_RSP].ctype, &avrc_rsp);
2391 
2392   return BT_STATUS_SUCCESS;
2393 }
2394 
2395 /***************************************************************************
2396  *
2397  * Function         add_to_now_playing_rsp
2398  *
2399  * Description      Response to command for adding speciafied media item
2400  *                  to Now Playing queue.
2401  *
2402  * Returns          bt_status_t
2403  *                      BT_STATUS_NOT_READY - when RC is not connected.
2404  *                      BT_STATUS_SUCCESS   - always if RC is connected
2405  *
2406  **************************************************************************/
add_to_now_playing_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status)2407 static bt_status_t add_to_now_playing_rsp(const RawAddress& bd_addr,
2408                                           btrc_status_t rsp_status) {
2409   tAVRC_RESPONSE avrc_rsp;
2410   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2411 
2412   BTIF_TRACE_DEBUG("%s", __func__);
2413   CHECK_RC_CONNECTED(p_dev);
2414 
2415   avrc_rsp.add_to_play.pdu = AVRC_PDU_ADD_TO_NOW_PLAYING;
2416   avrc_rsp.add_to_play.opcode = opcode_from_pdu(AVRC_PDU_ADD_TO_NOW_PLAYING);
2417   avrc_rsp.add_to_play.status = status_code_map[rsp_status];
2418 
2419   /* Send the response. */
2420   send_metamsg_rsp(p_dev, IDX_ADD_TO_NOW_PLAYING_RSP,
2421                    p_dev->rc_pdu_info[IDX_ADD_TO_NOW_PLAYING_RSP].label,
2422                    p_dev->rc_pdu_info[IDX_ADD_TO_NOW_PLAYING_RSP].ctype,
2423                    &avrc_rsp);
2424 
2425   return BT_STATUS_SUCCESS;
2426 }
2427 
2428 /***************************************************************************
2429  *
2430  * Function         play_item_rsp
2431  *
2432  * Description      Response to command for playing the specified media item.
2433  *
2434  * Returns          bt_status_t
2435  *                      BT_STATUS_NOT_READY - when RC is not connected.
2436  *                      BT_STATUS_SUCCESS   - always if RC is connected
2437  *
2438  **************************************************************************/
play_item_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status)2439 static bt_status_t play_item_rsp(const RawAddress& bd_addr,
2440                                  btrc_status_t rsp_status) {
2441   tAVRC_RESPONSE avrc_rsp;
2442   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2443 
2444   BTIF_TRACE_DEBUG("%s", __func__);
2445   CHECK_RC_CONNECTED(p_dev);
2446 
2447   avrc_rsp.play_item.pdu = AVRC_PDU_PLAY_ITEM;
2448   avrc_rsp.play_item.opcode = opcode_from_pdu(AVRC_PDU_PLAY_ITEM);
2449   avrc_rsp.play_item.status = status_code_map[rsp_status];
2450 
2451   /* Send the response. */
2452   send_metamsg_rsp(p_dev, IDX_PLAY_ITEM_RSP,
2453                    p_dev->rc_pdu_info[IDX_PLAY_ITEM_RSP].label,
2454                    p_dev->rc_pdu_info[IDX_PLAY_ITEM_RSP].ctype, &avrc_rsp);
2455 
2456   return BT_STATUS_SUCCESS;
2457 }
2458 
2459 /***************************************************************************
2460  *
2461  * Function         get_total_num_of_items_rsp
2462  *
2463  * Description      response to command to get the Number of Items
2464  *                  in the selected folder at the selected scope
2465  *
2466  * Returns          bt_status_t
2467  *                      BT_STATUS_NOT_READY - when RC is not connected.
2468  *                      BT_STATUS_SUCCESS   - always if RC is connected
2469  *
2470  **************************************************************************/
get_total_num_of_items_rsp(const RawAddress & bd_addr,btrc_status_t rsp_status,uint32_t uid_counter,uint32_t num_items)2471 static bt_status_t get_total_num_of_items_rsp(const RawAddress& bd_addr,
2472                                               btrc_status_t rsp_status,
2473                                               uint32_t uid_counter,
2474                                               uint32_t num_items) {
2475   tAVRC_RESPONSE avrc_rsp;
2476   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2477 
2478   BTIF_TRACE_DEBUG("%s", __func__);
2479   CHECK_RC_CONNECTED(p_dev);
2480 
2481   avrc_rsp.get_num_of_items.pdu = AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS;
2482   avrc_rsp.get_num_of_items.opcode =
2483       opcode_from_pdu(AVRC_PDU_GET_TOTAL_NUM_OF_ITEMS);
2484   avrc_rsp.get_num_of_items.num_items = num_items;
2485   avrc_rsp.get_num_of_items.uid_counter = uid_counter;
2486   avrc_rsp.get_num_of_items.status = status_code_map[rsp_status];
2487 
2488   /* Send the response. */
2489   send_metamsg_rsp(p_dev, IDX_GET_TOTAL_NUM_OF_ITEMS_RSP,
2490                    p_dev->rc_pdu_info[IDX_GET_TOTAL_NUM_OF_ITEMS_RSP].label,
2491                    p_dev->rc_pdu_info[IDX_GET_TOTAL_NUM_OF_ITEMS_RSP].ctype,
2492                    &avrc_rsp);
2493 
2494   return BT_STATUS_SUCCESS;
2495 }
2496 
2497 /***************************************************************************
2498  *
2499  * Function         set_volume
2500  *
2501  * Description      Send current volume setting to remote side.
2502  *                  Support limited to SetAbsoluteVolume
2503  *                  This can be enhanced to support Relative Volume (AVRCP 1.0).
2504  *                  With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
2505  *                  as opposed to absolute volume level
2506  * volume: Should be in the range 0-127. bit7 is reseved and cannot be set
2507  *
2508  * Returns          bt_status_t
2509  *
2510  **************************************************************************/
set_volume(uint8_t volume)2511 static bt_status_t set_volume(uint8_t volume) {
2512   BTIF_TRACE_DEBUG("%s: volume: %d", __func__, volume);
2513   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2514 
2515   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
2516     if (!btif_rc_cb.rc_multi_cb[idx].rc_connected) continue;
2517 
2518     if (btif_rc_cb.rc_multi_cb[idx].rc_volume == volume) {
2519       status = BT_STATUS_DONE;
2520       BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x", __func__,
2521                        volume);
2522       continue;
2523     }
2524 
2525     if ((btif_rc_cb.rc_multi_cb[idx].rc_volume == volume) ||
2526         btif_rc_cb.rc_multi_cb[idx].rc_state !=
2527             BTRC_CONNECTION_STATE_CONNECTED) {
2528       continue;
2529     }
2530 
2531     if ((btif_rc_cb.rc_multi_cb[idx].rc_features & BTA_AV_FEAT_RCTG) == 0) {
2532       status = BT_STATUS_NOT_READY;
2533       continue;
2534     }
2535 
2536     if (!(btif_rc_cb.rc_multi_cb[idx].rc_features & BTA_AV_FEAT_ADV_CTRL))
2537       continue;
2538 
2539     BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume: %d",
2540                      __func__, volume);
2541 
2542     tAVRC_COMMAND avrc_cmd = {.volume = {.opcode = AVRC_OP_VENDOR,
2543                                          .pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME,
2544                                          .status = AVRC_STS_NO_ERROR,
2545                                          .volume = volume}};
2546 
2547     BT_HDR* p_msg = NULL;
2548     if (AVRC_BldCommand(&avrc_cmd, &p_msg) != AVRC_STS_NO_ERROR) {
2549       BTIF_TRACE_ERROR(
2550           "%s: failed to build absolute volume command. status: 0x%02x",
2551           __func__, status);
2552       status = BT_STATUS_FAIL;
2553       continue;
2554     }
2555 
2556     rc_transaction_t* p_transaction = NULL;
2557     bt_status_t tran_status = get_transaction(&p_transaction);
2558 
2559     if (tran_status != BT_STATUS_SUCCESS || !p_transaction) {
2560       osi_free_and_reset((void**)&p_msg);
2561       BTIF_TRACE_ERROR(
2562           "%s: failed to obtain transaction details. status: 0x%02x", __func__,
2563           tran_status);
2564       status = BT_STATUS_FAIL;
2565       continue;
2566     }
2567 
2568     BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__,
2569                      p_transaction->lbl);
2570     BTA_AvMetaCmd(btif_rc_cb.rc_multi_cb[idx].rc_handle, p_transaction->lbl,
2571                   AVRC_CMD_CTRL, p_msg);
2572     status = BT_STATUS_SUCCESS;
2573   }
2574   return (bt_status_t)status;
2575 }
2576 
2577 /***************************************************************************
2578  *
2579  * Function         register_volumechange
2580  *
2581  * Description     Register for volume change notification from remote side.
2582  *
2583  * Returns          void
2584  *
2585  **************************************************************************/
2586 
register_volumechange(uint8_t lbl,btif_rc_device_cb_t * p_dev)2587 static void register_volumechange(uint8_t lbl, btif_rc_device_cb_t* p_dev) {
2588   tAVRC_COMMAND avrc_cmd = {0};
2589   BT_HDR* p_msg = NULL;
2590   tAVRC_STS BldResp = AVRC_STS_BAD_CMD;
2591   rc_transaction_t* p_transaction = NULL;
2592 
2593   BTIF_TRACE_DEBUG("%s: label: %d", __func__, lbl);
2594 
2595   avrc_cmd.cmd.opcode = 0x00;
2596   avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
2597   avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
2598   avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
2599   avrc_cmd.reg_notif.param = 0;
2600 
2601   BldResp = AVRC_BldCommand(&avrc_cmd, &p_msg);
2602   if (AVRC_STS_NO_ERROR == BldResp && p_msg) {
2603     p_transaction = get_transaction_by_lbl(lbl);
2604     if (p_transaction != NULL) {
2605       BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_NOTIF,
2606                     p_msg);
2607       BTIF_TRACE_DEBUG("%s: BTA_AvMetaCmd called", __func__);
2608     } else {
2609       osi_free(p_msg);
2610       BTIF_TRACE_ERROR("%s: transaction not obtained with label: %d", __func__,
2611                        lbl);
2612     }
2613   } else {
2614     BTIF_TRACE_ERROR("%s: failed to build command: %d", __func__, BldResp);
2615   }
2616 }
2617 
2618 /***************************************************************************
2619  *
2620  * Function         handle_rc_metamsg_rsp
2621  *
2622  * Description      Handle RC metamessage response
2623  *
2624  * Returns          void
2625  *
2626  **************************************************************************/
handle_rc_metamsg_rsp(tBTA_AV_META_MSG * pmeta_msg,btif_rc_device_cb_t * p_dev)2627 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg,
2628                                   btif_rc_device_cb_t* p_dev) {
2629   tAVRC_RESPONSE avrc_response = {0};
2630   uint8_t scratch_buf[512] = {0};
2631   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2632 
2633   BTIF_TRACE_DEBUG("%s: ", __func__);
2634 
2635   if (AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode &&
2636       (AVRC_RSP_CHANGED == pmeta_msg->code ||
2637        AVRC_RSP_INTERIM == pmeta_msg->code ||
2638        AVRC_RSP_ACCEPT == pmeta_msg->code || AVRC_RSP_REJ == pmeta_msg->code ||
2639        AVRC_RSP_NOT_IMPL == pmeta_msg->code)) {
2640     status = AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf,
2641                                sizeof(scratch_buf));
2642     BTIF_TRACE_DEBUG(
2643         "%s: code:%d, event ID: %d, PDU: %x, parsing status: %d, label: %d",
2644         __func__, pmeta_msg->code, avrc_response.reg_notif.event_id,
2645         avrc_response.reg_notif.pdu, status, pmeta_msg->label);
2646 
2647     if (status != AVRC_STS_NO_ERROR) {
2648       if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu &&
2649           AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id &&
2650           p_dev->rc_vol_label == pmeta_msg->label) {
2651         p_dev->rc_vol_label = MAX_LABEL;
2652         release_transaction(p_dev->rc_vol_label);
2653       } else if (AVRC_PDU_SET_ABSOLUTE_VOLUME == avrc_response.rsp.pdu) {
2654         release_transaction(pmeta_msg->label);
2655       }
2656       return;
2657     }
2658 
2659     if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu &&
2660         AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id &&
2661         p_dev->rc_vol_label != pmeta_msg->label) {
2662       // Just discard the message, if the device sends back with an incorrect
2663       // label
2664       BTIF_TRACE_DEBUG(
2665           "%s: Discarding register notification in rsp.code: %d and label: %d",
2666           __func__, pmeta_msg->code, pmeta_msg->label);
2667       return;
2668     }
2669 
2670     if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu &&
2671         AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id &&
2672         (AVRC_RSP_REJ == pmeta_msg->code ||
2673          AVRC_RSP_NOT_IMPL == pmeta_msg->code)) {
2674       BTIF_TRACE_DEBUG("%s remove AbsoluteVolume feature flag.", __func__);
2675       p_dev->rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
2676       handle_rc_features(p_dev);
2677       return;
2678     }
2679   } else {
2680     BTIF_TRACE_DEBUG(
2681         "%s: Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not "
2682         "processing it.",
2683         __func__, pmeta_msg->code, pmeta_msg->len);
2684     return;
2685   }
2686 
2687   if (AVRC_PDU_REGISTER_NOTIFICATION == avrc_response.rsp.pdu &&
2688       AVRC_EVT_VOLUME_CHANGE == avrc_response.reg_notif.event_id &&
2689       AVRC_RSP_CHANGED == pmeta_msg->code) {
2690     /* re-register for volume change notification */
2691     // Do not re-register for rejected case, as it might get into endless loop
2692     register_volumechange(p_dev->rc_vol_label, p_dev);
2693   } else if (AVRC_PDU_SET_ABSOLUTE_VOLUME == avrc_response.rsp.pdu) {
2694     /* free up the label here */
2695     release_transaction(pmeta_msg->label);
2696   }
2697 
2698   BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
2699                    __func__, dump_rc_pdu(avrc_response.pdu));
2700   btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response,
2701                             pmeta_msg->code, pmeta_msg->label, p_dev);
2702 }
2703 
2704 /***************************************************************************
2705  *
2706  * Function         iterate_supported_event_list_for_interim_rsp
2707  *
2708  * Description      iterator callback function to match the event and handle
2709  *                  timer cleanup
2710  * Returns          true to continue iterating, false to stop
2711  *
2712  **************************************************************************/
iterate_supported_event_list_for_interim_rsp(void * data,void * cb_data)2713 bool iterate_supported_event_list_for_interim_rsp(void* data, void* cb_data) {
2714   uint8_t* p_event_id;
2715   btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data;
2716 
2717   p_event_id = (uint8_t*)cb_data;
2718 
2719   if (p_event->event_id == *p_event_id) {
2720     p_event->status = eINTERIM;
2721     return false;
2722   }
2723   return true;
2724 }
2725 
2726 /***************************************************************************
2727  *
2728  * Function         iterate_supported_event_list_for_timeout
2729  *
2730  * Description      Iterator callback function for timeout handling.
2731  *                  As part of the failure handling, it releases the
2732  *                  transaction label and removes the event from list,
2733  *                  this event will not be requested again during
2734  *                  the lifetime of the connection.
2735  * Returns          false to stop iterating, true to continue
2736  *
2737  **************************************************************************/
iterate_supported_event_list_for_timeout(void * data,void * cb_data)2738 bool iterate_supported_event_list_for_timeout(void* data, void* cb_data) {
2739   rc_context_t* cntxt = (rc_context_t*)cb_data;
2740   uint8_t label = cntxt->label & 0xFF;
2741   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(cntxt->rc_addr);
2742   btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data;
2743 
2744   if (p_event->label == label) {
2745     list_remove(p_dev->rc_supported_event_list, p_event);
2746     return false;
2747   }
2748   return true;
2749 }
2750 
2751 /***************************************************************************
2752  *
2753  * Function         rc_notification_interim_timout
2754  *
2755  * Description      Interim response timeout handler.
2756  *                  Runs the iterator to check and clear the timed out event.
2757  *                  Proceeds to register for the unregistered events.
2758  * Returns          None
2759  *
2760  **************************************************************************/
rc_notification_interim_timout(uint8_t label,btif_rc_device_cb_t * p_dev)2761 static void rc_notification_interim_timout(uint8_t label,
2762                                            btif_rc_device_cb_t* p_dev) {
2763   list_node_t* node;
2764   rc_context_t cntxt;
2765   memset(&cntxt, 0, sizeof(rc_context_t));
2766   cntxt.label = label;
2767   cntxt.rc_addr = p_dev->rc_addr;
2768 
2769   list_foreach(p_dev->rc_supported_event_list,
2770                iterate_supported_event_list_for_timeout, &cntxt);
2771   /* Timeout happened for interim response for the registered event,
2772    * check if there are any pending for registration
2773    */
2774   node = list_begin(p_dev->rc_supported_event_list);
2775   while (node != NULL) {
2776     btif_rc_supported_event_t* p_event;
2777 
2778     p_event = (btif_rc_supported_event_t*)list_node(node);
2779     if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
2780       register_for_event_notification(p_event, p_dev);
2781       break;
2782     }
2783     node = list_next(node);
2784   }
2785   /* Todo. Need to initiate application settings query if this
2786    * is the last event registration.
2787    */
2788 }
2789 
2790 /***************************************************************************
2791  *
2792  * Function         btif_rc_status_cmd_timeout_handler
2793  *
2794  * Description      RC status command timeout handler (Runs in BTIF context).
2795  * Returns          None
2796  *
2797  **************************************************************************/
btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event,char * data)2798 static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2799                                                char* data) {
2800   btif_rc_timer_context_t* p_context;
2801   tAVRC_RESPONSE avrc_response = {0};
2802   tBTA_AV_META_MSG meta_msg;
2803   btif_rc_device_cb_t* p_dev = NULL;
2804 
2805   p_context = (btif_rc_timer_context_t*)data;
2806   memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2807   p_dev = btif_rc_get_device_by_bda(p_context->rc_addr);
2808   if (p_dev == NULL) {
2809     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
2810     return;
2811   }
2812   meta_msg.rc_handle = p_dev->rc_handle;
2813 
2814   switch (p_context->rc_status_cmd.pdu_id) {
2815     case AVRC_PDU_REGISTER_NOTIFICATION:
2816       rc_notification_interim_timout(p_context->rc_status_cmd.label, p_dev);
2817       break;
2818 
2819     case AVRC_PDU_GET_CAPABILITIES:
2820       avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2821       handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2822       break;
2823 
2824     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2825       avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
2826       handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
2827       break;
2828 
2829     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2830       avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
2831       handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
2832       break;
2833 
2834     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2835       avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
2836       handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
2837       break;
2838 
2839     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2840       avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
2841       handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
2842       break;
2843 
2844     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2845       avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
2846       handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
2847       break;
2848 
2849     case AVRC_PDU_GET_ELEMENT_ATTR:
2850       avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT;
2851       handle_get_elem_attr_response(&meta_msg, &avrc_response.get_attrs);
2852       break;
2853 
2854     case AVRC_PDU_GET_PLAY_STATUS:
2855       avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT;
2856       handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status);
2857       break;
2858   }
2859   release_transaction(p_context->rc_status_cmd.label);
2860 }
2861 
2862 /***************************************************************************
2863  *
2864  * Function         btif_rc_status_cmd_timer_timeout
2865  *
2866  * Description      RC status command timeout callback.
2867  *                  This is called from BTU context and switches to BTIF
2868  *                  context to handle the timeout events
2869  * Returns          None
2870  *
2871  **************************************************************************/
btif_rc_status_cmd_timer_timeout(void * data)2872 static void btif_rc_status_cmd_timer_timeout(void* data) {
2873   btif_rc_timer_context_t* p_data = (btif_rc_timer_context_t*)data;
2874 
2875   btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0, (char*)p_data,
2876                         sizeof(btif_rc_timer_context_t), NULL);
2877 }
2878 
2879 /***************************************************************************
2880  *
2881  * Function         btif_rc_control_cmd_timeout_handler
2882  *
2883  * Description      RC control command timeout handler (Runs in BTIF context).
2884  * Returns          None
2885  *
2886  **************************************************************************/
btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event,char * data)2887 static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2888                                                 char* data) {
2889   btif_rc_timer_context_t* p_context = (btif_rc_timer_context_t*)data;
2890   tAVRC_RESPONSE avrc_response = {0};
2891   tBTA_AV_META_MSG meta_msg;
2892   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(p_context->rc_addr);
2893   if (p_dev == NULL) {
2894     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
2895     return;
2896   }
2897 
2898   memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2899   meta_msg.rc_handle = p_dev->rc_handle;
2900 
2901   switch (p_context->rc_control_cmd.pdu_id) {
2902     case AVRC_PDU_SET_PLAYER_APP_VALUE:
2903       avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
2904       handle_set_app_attr_val_response(&meta_msg, &avrc_response.set_app_val);
2905       break;
2906   }
2907   release_transaction(p_context->rc_control_cmd.label);
2908 }
2909 
2910 /***************************************************************************
2911  *
2912  * Function         btif_rc_control_cmd_timer_timeout
2913  *
2914  * Description      RC control command timeout callback.
2915  *                  This is called from BTU context and switches to BTIF
2916  *                  context to handle the timeout events
2917  * Returns          None
2918  *
2919  **************************************************************************/
btif_rc_control_cmd_timer_timeout(void * data)2920 static void btif_rc_control_cmd_timer_timeout(void* data) {
2921   btif_rc_timer_context_t* p_data = (btif_rc_timer_context_t*)data;
2922 
2923   btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0, (char*)p_data,
2924                         sizeof(btif_rc_timer_context_t), NULL);
2925 }
2926 
2927 /***************************************************************************
2928  *
2929  * Function         btif_rc_play_status_timeout_handler
2930  *
2931  * Description      RC play status timeout handler (Runs in BTIF context).
2932  * Returns          None
2933  *
2934  **************************************************************************/
btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event,char * p_data)2935 static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event,
2936                                                 char* p_data) {
2937   btif_rc_handle_t* rc_handle = (btif_rc_handle_t*)p_data;
2938   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(rc_handle->handle);
2939   if (p_dev == NULL) {
2940     BTIF_TRACE_ERROR("%s timeout handler but no device found for handle %d",
2941                      __func__, rc_handle->handle);
2942     return;
2943   }
2944   get_play_status_cmd(p_dev);
2945   rc_start_play_status_timer(p_dev);
2946 }
2947 
2948 /***************************************************************************
2949  *
2950  * Function         btif_rc_play_status_timer_timeout
2951  *
2952  * Description      RC play status timeout callback.
2953  *                  This is called from BTU context and switches to BTIF
2954  *                  context to handle the timeout events
2955  * Returns          None
2956  *
2957  **************************************************************************/
btif_rc_play_status_timer_timeout(void * data)2958 static void btif_rc_play_status_timer_timeout(void* data) {
2959   btif_rc_handle_t rc_handle;
2960   rc_handle.handle = PTR_TO_UINT(data);
2961   BTIF_TRACE_DEBUG("%s called with handle: %d", __func__, rc_handle);
2962   btif_transfer_context(btif_rc_play_status_timeout_handler, 0,
2963                         (char*)(&rc_handle), sizeof(btif_rc_handle_t), NULL);
2964 }
2965 
2966 /***************************************************************************
2967  *
2968  * Function         rc_start_play_status_timer
2969  *
2970  * Description      Helper function to start the timer to fetch play status.
2971  * Returns          None
2972  *
2973  **************************************************************************/
rc_start_play_status_timer(btif_rc_device_cb_t * p_dev)2974 static void rc_start_play_status_timer(btif_rc_device_cb_t* p_dev) {
2975   /* Start the Play status timer only if it is not started */
2976   if (!alarm_is_scheduled(p_dev->rc_play_status_timer)) {
2977     if (p_dev->rc_play_status_timer == NULL) {
2978       p_dev->rc_play_status_timer = alarm_new("p_dev->rc_play_status_timer");
2979     }
2980     alarm_set_on_mloop(
2981         p_dev->rc_play_status_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2982         btif_rc_play_status_timer_timeout, UINT_TO_PTR(p_dev->rc_handle));
2983   }
2984 }
2985 
2986 /***************************************************************************
2987  *
2988  * Function         rc_stop_play_status_timer
2989  *
2990  * Description      Helper function to stop the play status timer.
2991  * Returns          None
2992  *
2993  **************************************************************************/
rc_stop_play_status_timer(btif_rc_device_cb_t * p_dev)2994 void rc_stop_play_status_timer(btif_rc_device_cb_t* p_dev) {
2995   alarm_cancel(p_dev->rc_play_status_timer);
2996 }
2997 
2998 /***************************************************************************
2999  *
3000  * Function         register_for_event_notification
3001  *
3002  * Description      Helper function registering notification events
3003  *                  sets an interim response timeout to handle if the remote
3004  *                  does not respond.
3005  * Returns          None
3006  *
3007  **************************************************************************/
register_for_event_notification(btif_rc_supported_event_t * p_event,btif_rc_device_cb_t * p_dev)3008 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
3009                                             btif_rc_device_cb_t* p_dev) {
3010   rc_transaction_t* p_transaction = NULL;
3011   bt_status_t status = get_transaction(&p_transaction);
3012   if (status != BT_STATUS_SUCCESS) {
3013     BTIF_TRACE_ERROR("%s: no more transaction labels: %d", __func__, status);
3014     return;
3015   }
3016 
3017   status = register_notification_cmd(p_transaction->lbl, p_event->event_id, 0,
3018                                      p_dev);
3019   if (status != BT_STATUS_SUCCESS) {
3020     BTIF_TRACE_ERROR("%s: Error in Notification registration: %d", __func__,
3021                      status);
3022     release_transaction(p_transaction->lbl);
3023     return;
3024   }
3025 
3026   btif_rc_timer_context_t* p_context = &p_transaction->txn_timer_context;
3027   p_event->label = p_transaction->lbl;
3028   p_event->status = eREGISTERED;
3029   p_context->rc_status_cmd.label = p_transaction->lbl;
3030   p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
3031   p_context->rc_addr = p_dev->rc_addr;
3032 
3033   alarm_free(p_transaction->txn_timer);
3034   p_transaction->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
3035   alarm_set_on_mloop(p_transaction->txn_timer, BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
3036                      btif_rc_status_cmd_timer_timeout, p_context);
3037 }
3038 
start_status_command_timer(uint8_t pdu_id,rc_transaction_t * p_txn,btif_rc_device_cb_t * p_dev)3039 static void start_status_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn,
3040                                        btif_rc_device_cb_t* p_dev) {
3041   btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context;
3042   p_context->rc_status_cmd.label = p_txn->lbl;
3043   p_context->rc_status_cmd.pdu_id = pdu_id;
3044   p_context->rc_addr = p_dev->rc_addr;
3045 
3046   alarm_free(p_txn->txn_timer);
3047   p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
3048   alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
3049                      btif_rc_status_cmd_timer_timeout, p_context);
3050 }
3051 
start_control_command_timer(uint8_t pdu_id,rc_transaction_t * p_txn,btif_rc_device_cb_t * p_dev)3052 static void start_control_command_timer(uint8_t pdu_id, rc_transaction_t* p_txn,
3053                                         btif_rc_device_cb_t* p_dev) {
3054   btif_rc_timer_context_t* p_context = &p_txn->txn_timer_context;
3055   p_context->rc_control_cmd.label = p_txn->lbl;
3056   p_context->rc_control_cmd.pdu_id = pdu_id;
3057   p_context->rc_addr = p_dev->rc_addr;
3058 
3059   alarm_free(p_txn->txn_timer);
3060   p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer");
3061   alarm_set_on_mloop(p_txn->txn_timer, BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
3062                      btif_rc_control_cmd_timer_timeout, p_context);
3063 }
3064 
build_and_send_vendor_cmd(tAVRC_COMMAND * avrc_cmd,tBTA_AV_CODE cmd_code,btif_rc_device_cb_t * p_dev)3065 bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd,
3066                                       tBTA_AV_CODE cmd_code,
3067                                       btif_rc_device_cb_t* p_dev) {
3068   rc_transaction_t* p_transaction = NULL;
3069   bt_status_t tran_status = get_transaction(&p_transaction);
3070   if (BT_STATUS_SUCCESS != tran_status) return BT_STATUS_FAIL;
3071 
3072   BT_HDR* p_msg = NULL;
3073   tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg);
3074   if (status == AVRC_STS_NO_ERROR && p_msg != NULL) {
3075     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
3076     BTIF_TRACE_DEBUG("%s: %s msgreq being sent out with label: %d", __func__,
3077                      dump_rc_pdu(avrc_cmd->pdu), p_transaction->lbl);
3078     BTA_AvVendorCmd(p_dev->rc_handle, p_transaction->lbl, cmd_code, data_start,
3079                     p_msg->len);
3080     status = BT_STATUS_SUCCESS;
3081     if (cmd_code == AVRC_CMD_STATUS) {
3082       start_status_command_timer(avrc_cmd->pdu, p_transaction, p_dev);
3083     } else if (cmd_code == AVRC_CMD_CTRL) {
3084       start_control_command_timer(avrc_cmd->pdu, p_transaction, p_dev);
3085     }
3086   } else {
3087     BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__,
3088                      status);
3089   }
3090   osi_free(p_msg);
3091   return (bt_status_t)status;
3092 }
3093 
3094 /***************************************************************************
3095  *
3096  * Function         handle_get_capability_response
3097  *
3098  * Description      Handles the get_cap_response to populate company id info
3099  *                  and query the supported events.
3100  *                  Initiates Notification registration for events supported
3101  * Returns          None
3102  *
3103  **************************************************************************/
handle_get_capability_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CAPS_RSP * p_rsp)3104 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg,
3105                                            tAVRC_GET_CAPS_RSP* p_rsp) {
3106   int xx = 0;
3107   btif_rc_device_cb_t* p_dev =
3108       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3109 
3110   /* Todo: Do we need to retry on command timeout */
3111   if (p_rsp->status != AVRC_STS_NO_ERROR) {
3112     BTIF_TRACE_ERROR("%s: Error capability response: 0x%02X", __func__,
3113                      p_rsp->status);
3114     return;
3115   }
3116 
3117   if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED) {
3118     btif_rc_supported_event_t* p_event;
3119 
3120     /* Todo: Check if list can be active when we hit here */
3121     p_dev->rc_supported_event_list = list_new(osi_free);
3122     for (xx = 0; xx < p_rsp->count; xx++) {
3123       /* Skip registering for Play position change notification */
3124       if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE) ||
3125           (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE) ||
3126           (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE) ||
3127           (p_rsp->param.event_id[xx] == AVRC_EVT_ADDR_PLAYER_CHANGE) ||
3128           (p_rsp->param.event_id[xx] == AVRC_EVT_UIDS_CHANGE)) {
3129         p_event = (btif_rc_supported_event_t*)osi_malloc(
3130             sizeof(btif_rc_supported_event_t));
3131         p_event->event_id = p_rsp->param.event_id[xx];
3132         p_event->status = eNOT_REGISTERED;
3133         list_append(p_dev->rc_supported_event_list, p_event);
3134       }
3135     }
3136     p_event =
3137         (btif_rc_supported_event_t*)list_front(p_dev->rc_supported_event_list);
3138     if (p_event != NULL) {
3139       register_for_event_notification(p_event, p_dev);
3140     }
3141   } else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
3142     getcapabilities_cmd(AVRC_CAP_EVENTS_SUPPORTED, p_dev);
3143     BTIF_TRACE_EVENT("%s: AVRC_CAP_COMPANY_ID: ", __func__);
3144     for (xx = 0; xx < p_rsp->count; xx++) {
3145       BTIF_TRACE_EVENT("%s: company_id: %d", __func__,
3146                        p_rsp->param.company_id[xx]);
3147     }
3148   }
3149 }
3150 
rc_is_track_id_valid(tAVRC_UID uid)3151 bool rc_is_track_id_valid(tAVRC_UID uid) {
3152   tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
3153 
3154   if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0) {
3155     return false;
3156   } else {
3157     return true;
3158   }
3159 }
3160 
3161 /***************************************************************************
3162  *
3163  * Function         handle_notification_response
3164  *
3165  * Description      Main handler for notification responses to registered events
3166  *                  1. Register for unregistered event(in interim response path)
3167  *                  2. After registering for all supported events, start
3168  *                     retrieving application settings and values
3169  *                  3. Reregister for events on getting changed response
3170  *                  4. Run play status timer for getting position when the
3171  *                     status changes to playing
3172  *                  5. Get the Media details when the track change happens
3173  *                     or track change interim response is received with
3174  *                     valid track id
3175  *                  6. HAL callback for play status change and application
3176  *                     setting change
3177  * Returns          None
3178  *
3179  **************************************************************************/
handle_notification_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_REG_NOTIF_RSP * p_rsp)3180 static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg,
3181                                          tAVRC_REG_NOTIF_RSP* p_rsp) {
3182   btif_rc_device_cb_t* p_dev =
3183       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3184   uint32_t attr_list[] = {
3185       AVRC_MEDIA_ATTR_ID_TITLE,       AVRC_MEDIA_ATTR_ID_ARTIST,
3186       AVRC_MEDIA_ATTR_ID_ALBUM,       AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3187       AVRC_MEDIA_ATTR_ID_NUM_TRACKS,  AVRC_MEDIA_ATTR_ID_GENRE,
3188       AVRC_MEDIA_ATTR_ID_PLAYING_TIME};
3189 
3190   if (p_dev == NULL) {
3191     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3192     return;
3193   }
3194 
3195 
3196   if (pmeta_msg->code == AVRC_RSP_INTERIM) {
3197     btif_rc_supported_event_t* p_event;
3198     list_node_t* node;
3199 
3200     BTIF_TRACE_DEBUG("%s: Interim response: 0x%2X ", __func__, p_rsp->event_id);
3201     switch (p_rsp->event_id) {
3202       case AVRC_EVT_PLAY_STATUS_CHANGE:
3203         /* Start timer to get play status periodically
3204          * if the play state is playing.
3205          */
3206         if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING ||
3207             p_rsp->param.play_status == AVRC_PLAYSTATE_REV_SEEK ||
3208             p_rsp->param.play_status == AVRC_PLAYSTATE_FWD_SEEK) {
3209           rc_start_play_status_timer(p_dev);
3210         }
3211         do_in_jni_thread(
3212             FROM_HERE,
3213             base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb,
3214                        p_dev->rc_addr,
3215                        (btrc_play_status_t)p_rsp->param.play_status));
3216         break;
3217 
3218       case AVRC_EVT_TRACK_CHANGE:
3219         if (rc_is_track_id_valid(p_rsp->param.track) != true) {
3220           break;
3221         } else {
3222           uint8_t* p_data = p_rsp->param.track;
3223           /* Update the UID for current track
3224            * Attributes will be fetched after the AVRCP procedure
3225            */
3226           BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
3227         }
3228         break;
3229 
3230       case AVRC_EVT_APP_SETTING_CHANGE:
3231         break;
3232 
3233       case AVRC_EVT_NOW_PLAYING_CHANGE:
3234         break;
3235 
3236       case AVRC_EVT_AVAL_PLAYERS_CHANGE:
3237         break;
3238 
3239       case AVRC_EVT_ADDR_PLAYER_CHANGE:
3240         do_in_jni_thread(
3241             FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->set_addressed_player_cb,
3242                                   p_dev->rc_addr, BTRC_STS_ADDR_PLAY_CHGD));
3243         break;
3244 
3245       case AVRC_EVT_UIDS_CHANGE:
3246         break;
3247 
3248       case AVRC_EVT_TRACK_REACHED_END:
3249       case AVRC_EVT_TRACK_REACHED_START:
3250       case AVRC_EVT_PLAY_POS_CHANGED:
3251       case AVRC_EVT_BATTERY_STATUS_CHANGE:
3252       case AVRC_EVT_SYSTEM_STATUS_CHANGE:
3253       default:
3254         BTIF_TRACE_ERROR("%s: Unhandled interim response: 0x%2X", __func__,
3255                          p_rsp->event_id);
3256         return;
3257     }
3258 
3259     list_foreach(p_dev->rc_supported_event_list,
3260                  iterate_supported_event_list_for_interim_rsp,
3261                  &p_rsp->event_id);
3262 
3263     node = list_begin(p_dev->rc_supported_event_list);
3264 
3265     while (node != NULL) {
3266       p_event = (btif_rc_supported_event_t*)list_node(node);
3267       if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
3268         register_for_event_notification(p_event, p_dev);
3269         break;
3270       }
3271       node = list_next(node);
3272       p_event = NULL;
3273     }
3274     /* Registered for all events, we can request application settings */
3275     if (p_event == NULL && !p_dev->rc_app_settings.query_started) {
3276       /* we need to do this only if remote TG supports
3277        * player application settings
3278        */
3279       p_dev->rc_app_settings.query_started = true;
3280       if (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING) {
3281         list_player_app_setting_attrib_cmd(p_dev);
3282       } else {
3283         BTIF_TRACE_DEBUG("%s: App setting not supported, complete procedure",
3284                          __func__);
3285         rc_ctrl_procedure_complete(p_dev);
3286       }
3287     }
3288   } else if (pmeta_msg->code == AVRC_RSP_CHANGED) {
3289     btif_rc_supported_event_t* p_event;
3290     list_node_t* node;
3291 
3292     BTIF_TRACE_DEBUG("%s: Notification completed: 0x%2X ", __func__,
3293                      p_rsp->event_id);
3294 
3295     node = list_begin(p_dev->rc_supported_event_list);
3296 
3297     while (node != NULL) {
3298       p_event = (btif_rc_supported_event_t*)list_node(node);
3299       if (p_event != NULL && p_event->event_id == p_rsp->event_id) {
3300         p_event->status = eNOT_REGISTERED;
3301         register_for_event_notification(p_event, p_dev);
3302         break;
3303       }
3304       node = list_next(node);
3305     }
3306 
3307     switch (p_rsp->event_id) {
3308       case AVRC_EVT_PLAY_STATUS_CHANGE:
3309         /* Start timer to get play status periodically
3310          * if the play state is playing.
3311          */
3312         if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING) {
3313           rc_start_play_status_timer(p_dev);
3314           get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list,
3315                                     p_dev);
3316         } else {
3317           rc_stop_play_status_timer(p_dev);
3318         }
3319         do_in_jni_thread(
3320             FROM_HERE,
3321             base::Bind(bt_rc_ctrl_callbacks->play_status_changed_cb,
3322                        p_dev->rc_addr,
3323                        (btrc_play_status_t)p_rsp->param.play_status));
3324 
3325         break;
3326 
3327       case AVRC_EVT_TRACK_CHANGE:
3328         if (rc_is_track_id_valid(p_rsp->param.track) != true) {
3329           break;
3330         }
3331         get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev);
3332         break;
3333 
3334       case AVRC_EVT_APP_SETTING_CHANGE: {
3335         btrc_player_settings_t app_settings;
3336         uint16_t xx;
3337 
3338         app_settings.num_attr = p_rsp->param.player_setting.num_attr;
3339         for (xx = 0; xx < app_settings.num_attr; xx++) {
3340           app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
3341           app_settings.attr_values[xx] =
3342               p_rsp->param.player_setting.attr_value[xx];
3343         }
3344         do_in_jni_thread(
3345             FROM_HERE,
3346             base::Bind(
3347                 bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
3348                 p_dev->rc_addr, app_settings));
3349       } break;
3350 
3351       case AVRC_EVT_NOW_PLAYING_CHANGE:
3352         break;
3353 
3354       case AVRC_EVT_AVAL_PLAYERS_CHANGE:
3355         break;
3356 
3357       case AVRC_EVT_ADDR_PLAYER_CHANGE:
3358         break;
3359 
3360       case AVRC_EVT_UIDS_CHANGE:
3361         break;
3362 
3363       case AVRC_EVT_TRACK_REACHED_END:
3364       case AVRC_EVT_TRACK_REACHED_START:
3365       case AVRC_EVT_PLAY_POS_CHANGED:
3366       case AVRC_EVT_BATTERY_STATUS_CHANGE:
3367       case AVRC_EVT_SYSTEM_STATUS_CHANGE:
3368       default:
3369         BTIF_TRACE_ERROR("%s: Unhandled completion response: 0x%2X", __func__,
3370                          p_rsp->event_id);
3371         return;
3372     }
3373   }
3374 }
3375 
3376 /***************************************************************************
3377  *
3378  * Function         handle_app_attr_response
3379  *
3380  * Description      handles the the application attributes response and
3381  *                  initiates procedure to fetch the attribute values
3382  * Returns          None
3383  *
3384  **************************************************************************/
handle_app_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_ATTR_RSP * p_rsp)3385 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg,
3386                                      tAVRC_LIST_APP_ATTR_RSP* p_rsp) {
3387   uint8_t xx;
3388   btif_rc_device_cb_t* p_dev =
3389       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3390 
3391   if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
3392     BTIF_TRACE_ERROR("%s: Error getting Player application settings: 0x%2X",
3393                      __func__, p_rsp->status);
3394     rc_ctrl_procedure_complete(p_dev);
3395     return;
3396   }
3397 
3398   for (xx = 0; xx < p_rsp->num_attr; xx++) {
3399     uint8_t st_index;
3400 
3401     if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT) {
3402       st_index = p_dev->rc_app_settings.num_ext_attrs;
3403       p_dev->rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
3404       p_dev->rc_app_settings.num_ext_attrs++;
3405     } else {
3406       st_index = p_dev->rc_app_settings.num_attrs;
3407       p_dev->rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
3408       p_dev->rc_app_settings.num_attrs++;
3409     }
3410   }
3411   p_dev->rc_app_settings.attr_index = 0;
3412   p_dev->rc_app_settings.ext_attr_index = 0;
3413   p_dev->rc_app_settings.ext_val_index = 0;
3414   if (p_rsp->num_attr) {
3415     list_player_app_setting_value_cmd(p_dev->rc_app_settings.attrs[0].attr_id,
3416                                       p_dev);
3417   } else {
3418     BTIF_TRACE_ERROR("%s: No Player application settings found", __func__);
3419   }
3420 }
3421 
3422 /***************************************************************************
3423  *
3424  * Function         handle_app_val_response
3425  *
3426  * Description      handles the the attributes value response and if extended
3427  *                  menu is available, it initiates query for the attribute
3428  *                  text. If not, it initiates procedure to get the current
3429  *                  attribute values and calls the HAL callback for provding
3430  *                  application settings information.
3431  * Returns          None
3432  *
3433  **************************************************************************/
handle_app_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_VALUES_RSP * p_rsp)3434 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg,
3435                                     tAVRC_LIST_APP_VALUES_RSP* p_rsp) {
3436   uint8_t xx, attr_index;
3437   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
3438   btif_rc_player_app_settings_t* p_app_settings;
3439   btif_rc_device_cb_t* p_dev =
3440       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3441 
3442   /* Todo: Do we need to retry on command timeout */
3443   if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
3444     BTIF_TRACE_ERROR("%s: Error fetching attribute values: 0x%02X", __func__,
3445                      p_rsp->status);
3446     return;
3447   }
3448 
3449   p_app_settings = &p_dev->rc_app_settings;
3450 
3451   if (p_app_settings->attr_index < p_app_settings->num_attrs) {
3452     attr_index = p_app_settings->attr_index;
3453     p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
3454     for (xx = 0; xx < p_rsp->num_val; xx++) {
3455       p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
3456     }
3457     attr_index++;
3458     p_app_settings->attr_index++;
3459     if (attr_index < p_app_settings->num_attrs) {
3460       list_player_app_setting_value_cmd(
3461           p_app_settings->attrs[p_app_settings->attr_index].attr_id, p_dev);
3462     } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
3463       attr_index = 0;
3464       p_app_settings->ext_attr_index = 0;
3465       list_player_app_setting_value_cmd(
3466           p_app_settings->ext_attrs[attr_index].attr_id, p_dev);
3467     } else {
3468       for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
3469         attrs[xx] = p_app_settings->attrs[xx].attr_id;
3470       }
3471       get_player_app_setting_cmd(p_app_settings->num_attrs, attrs, p_dev);
3472       do_in_jni_thread(
3473           FROM_HERE,
3474           base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
3475                      p_dev->rc_addr, p_app_settings->num_attrs,
3476                      p_app_settings->attrs, 0, nullptr));
3477     }
3478   } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
3479     attr_index = p_app_settings->ext_attr_index;
3480     p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
3481     for (xx = 0; xx < p_rsp->num_val; xx++) {
3482       p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val =
3483           p_rsp->vals[xx];
3484     }
3485     attr_index++;
3486     p_app_settings->ext_attr_index++;
3487     if (attr_index < p_app_settings->num_ext_attrs) {
3488       list_player_app_setting_value_cmd(
3489           p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id,
3490           p_dev);
3491     } else {
3492       uint8_t attr[AVRC_MAX_APP_ATTR_SIZE];
3493 
3494       for (uint8_t xx = 0; xx < p_app_settings->num_ext_attrs; xx++) {
3495         attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
3496       }
3497       get_player_app_setting_attr_text_cmd(attr, p_app_settings->num_ext_attrs,
3498                                            p_dev);
3499     }
3500   }
3501 }
3502 
3503 /***************************************************************************
3504  *
3505  * Function         handle_app_cur_val_response
3506  *
3507  * Description      handles the the get attributes value response.
3508  *
3509  * Returns          None
3510  *
3511  **************************************************************************/
handle_app_cur_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CUR_APP_VALUE_RSP * p_rsp)3512 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
3513                                         tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp) {
3514   btrc_player_settings_t app_settings;
3515   uint16_t xx;
3516   btif_rc_device_cb_t* p_dev = NULL;
3517 
3518   /* Todo: Do we need to retry on command timeout */
3519   if (p_rsp->status != AVRC_STS_NO_ERROR) {
3520     BTIF_TRACE_ERROR("%s: Error fetching current settings: 0x%02X", __func__,
3521                      p_rsp->status);
3522     return;
3523   }
3524   p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3525   if (p_dev == NULL) {
3526     BTIF_TRACE_ERROR("%s: Error in getting Device Address", __func__);
3527     osi_free_and_reset((void**)&p_rsp->p_vals);
3528     return;
3529   }
3530 
3531 
3532   app_settings.num_attr = p_rsp->num_val;
3533 
3534   if (app_settings.num_attr > BTRC_MAX_APP_SETTINGS) {
3535     android_errorWriteLog(0x534e4554, "73824150");
3536     app_settings.num_attr = BTRC_MAX_APP_SETTINGS;
3537   }
3538 
3539   for (xx = 0; xx < app_settings.num_attr; xx++) {
3540     app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
3541     app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
3542   }
3543 
3544   do_in_jni_thread(
3545       FROM_HERE,
3546       base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
3547                  p_dev->rc_addr, app_settings));
3548   /* Application settings are fetched only once for initial values
3549    * initiate anything that follows after RC procedure.
3550    * Defer it if browsing is supported till players query
3551    */
3552   rc_ctrl_procedure_complete(p_dev);
3553   osi_free_and_reset((void**)&p_rsp->p_vals);
3554 }
3555 
3556 /***************************************************************************
3557  *
3558  * Function         handle_app_attr_txt_response
3559  *
3560  * Description      handles the the get attributes text response, if fails
3561  *                  calls HAL callback with just normal settings and initiates
3562  *                  query for current settings else initiates query for value
3563  *                  text
3564  * Returns          None
3565  *
3566  **************************************************************************/
handle_app_attr_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)3567 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
3568                                          tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
3569   uint8_t xx;
3570   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
3571   btif_rc_player_app_settings_t* p_app_settings;
3572   btif_rc_device_cb_t* p_dev =
3573       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3574 
3575   if (p_dev == NULL) {
3576     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3577     return;
3578   }
3579 
3580   p_app_settings = &p_dev->rc_app_settings;
3581 
3582   /* Todo: Do we need to retry on command timeout */
3583   if (p_rsp->status != AVRC_STS_NO_ERROR) {
3584     uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
3585 
3586     BTIF_TRACE_ERROR("%s: Error fetching attribute text: 0x%02X", __func__,
3587                      p_rsp->status);
3588     /* Not able to fetch Text for extended Menu, skip the process
3589      * and cleanup used memory. Proceed to get the current settings
3590      * for standard attributes.
3591      */
3592     p_app_settings->num_ext_attrs = 0;
3593     for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
3594       osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
3595     }
3596     p_app_settings->ext_attr_index = 0;
3597 
3598     if (p_dev) {
3599       for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
3600         attrs[xx] = p_app_settings->attrs[xx].attr_id;
3601       }
3602 
3603       do_in_jni_thread(
3604           FROM_HERE,
3605           base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
3606                      p_dev->rc_addr, p_app_settings->num_attrs,
3607                      p_app_settings->attrs, 0, nullptr));
3608       get_player_app_setting_cmd(xx, attrs, p_dev);
3609     }
3610     return;
3611   }
3612 
3613   for (xx = 0; xx < p_rsp->num_attr; xx++) {
3614     uint8_t x;
3615     for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
3616       if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) {
3617         p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
3618         p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
3619         p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
3620         break;
3621       }
3622     }
3623   }
3624 
3625   for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++) {
3626     vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
3627   }
3628   get_player_app_setting_value_text_cmd(vals, xx, p_dev);
3629 }
3630 
3631 /***************************************************************************
3632  *
3633  * Function         handle_app_attr_val_txt_response
3634  *
3635  * Description      handles the the get attributes value text response, if fails
3636  *                  calls HAL callback with just normal settings and initiates
3637  *                  query for current settings
3638  * Returns          None
3639  *
3640  **************************************************************************/
handle_app_attr_val_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)3641 static void handle_app_attr_val_txt_response(
3642     tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
3643   uint8_t xx, attr_index;
3644   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
3645   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
3646   btif_rc_player_app_settings_t* p_app_settings;
3647   btif_rc_device_cb_t* p_dev =
3648       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3649 
3650   if (p_dev == NULL) {
3651     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3652     return;
3653   }
3654 
3655   p_app_settings = &p_dev->rc_app_settings;
3656 
3657   /* Todo: Do we need to retry on command timeout */
3658   if (p_rsp->status != AVRC_STS_NO_ERROR) {
3659     uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
3660 
3661     BTIF_TRACE_ERROR("%s: Error fetching attribute value text: 0x%02X",
3662                      __func__, p_rsp->status);
3663 
3664     /* Not able to fetch Text for extended Menu, skip the process
3665      * and cleanup used memory. Proceed to get the current settings
3666      * for standard attributes.
3667      */
3668     p_app_settings->num_ext_attrs = 0;
3669     for (xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
3670       int x;
3671       btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
3672 
3673       for (x = 0; x < p_ext_attr->num_val; x++)
3674         osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
3675       p_ext_attr->num_val = 0;
3676       osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
3677     }
3678     p_app_settings->ext_attr_index = 0;
3679 
3680     for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
3681       attrs[xx] = p_app_settings->attrs[xx].attr_id;
3682     }
3683     do_in_jni_thread(
3684         FROM_HERE, base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
3685                               p_dev->rc_addr, p_app_settings->num_attrs,
3686                               p_app_settings->attrs, 0, nullptr));
3687 
3688     get_player_app_setting_cmd(xx, attrs, p_dev);
3689     return;
3690   }
3691 
3692   for (xx = 0; xx < p_rsp->num_attr; xx++) {
3693     uint8_t x;
3694     btrc_player_app_ext_attr_t* p_ext_attr;
3695     p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
3696     for (x = 0; x < p_rsp->num_attr; x++) {
3697       if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) {
3698         p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
3699         p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
3700         p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
3701         break;
3702       }
3703     }
3704   }
3705   p_app_settings->ext_val_index++;
3706 
3707   if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) {
3708     attr_index = p_app_settings->ext_val_index;
3709     for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++) {
3710       vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
3711     }
3712     get_player_app_setting_value_text_cmd(vals, xx, p_dev);
3713   } else {
3714     uint8_t x;
3715 
3716     for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
3717       attrs[xx] = p_app_settings->attrs[xx].attr_id;
3718     }
3719     for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
3720       attrs[xx + x] = p_app_settings->ext_attrs[x].attr_id;
3721     }
3722     do_in_jni_thread(
3723         FROM_HERE,
3724         base::Bind(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
3725                    p_dev->rc_addr, p_app_settings->num_attrs,
3726                    p_app_settings->attrs, p_app_settings->num_ext_attrs,
3727                    p_app_settings->ext_attrs));
3728     get_player_app_setting_cmd(xx + x, attrs, p_dev);
3729 
3730     /* Free the application settings information after sending to
3731      * application.
3732      */
3733     do_in_jni_thread(FROM_HERE, base::Bind(cleanup_app_attr_val_txt_response,
3734                                            p_app_settings));
3735     p_app_settings->num_attrs = 0;
3736   }
3737 }
3738 
3739 /***************************************************************************
3740  *
3741  * Function         cleanup_app_attr_val_txt_response
3742  *
3743  * Description      Frees the memory that was allocated for reporting player
3744  *                  application settings.
3745  * Returns          None
3746  **************************************************************************/
cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t * p_app_settings)3747 static void cleanup_app_attr_val_txt_response(
3748     btif_rc_player_app_settings_t* p_app_settings) {
3749   for (uint8_t xx = 0; xx < p_app_settings->ext_attr_index; xx++) {
3750     int x;
3751     btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
3752     for (x = 0; x < p_ext_attr->num_val; x++) {
3753       osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
3754     }
3755     p_ext_attr->num_val = 0;
3756     osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
3757   }
3758 }
3759 
3760 /***************************************************************************
3761  *
3762  * Function         handle_set_app_attr_val_response
3763  *
3764  * Description      handles the the set attributes value response, if fails
3765  *                  calls HAL callback to indicate the failure
3766  * Returns          None
3767  *
3768  **************************************************************************/
handle_set_app_attr_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP * p_rsp)3769 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg,
3770                                              tAVRC_RSP* p_rsp) {
3771   uint8_t accepted = 0;
3772   btif_rc_device_cb_t* p_dev =
3773       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3774 
3775   if (p_dev == NULL) {
3776     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3777     return;
3778   }
3779 
3780 
3781   /* For timeout pmeta_msg will be NULL, else we need to
3782    * check if this is accepted by TG
3783    */
3784   if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) {
3785     accepted = 1;
3786   }
3787   do_in_jni_thread(FROM_HERE,
3788                    base::Bind(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb,
3789                               p_dev->rc_addr, accepted));
3790 }
3791 
3792 /***************************************************************************
3793  *
3794  * Function         handle_get_elem_attr_response
3795  *
3796  * Description      handles the the element attributes response, calls
3797  *                  HAL callback to update track change information.
3798  * Returns          None
3799  *
3800  **************************************************************************/
handle_get_elem_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ATTRS_RSP * p_rsp)3801 static void handle_get_elem_attr_response(tBTA_AV_META_MSG* pmeta_msg,
3802                                           tAVRC_GET_ATTRS_RSP* p_rsp) {
3803   btif_rc_device_cb_t* p_dev =
3804       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3805 
3806   if (p_rsp->status == AVRC_STS_NO_ERROR) {
3807     size_t buf_size = p_rsp->num_attrs * sizeof(btrc_element_attr_val_t);
3808     btrc_element_attr_val_t* p_attr =
3809         (btrc_element_attr_val_t*)osi_calloc(buf_size);
3810 
3811     if (p_dev == NULL) {
3812       BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3813       return;
3814     }
3815 
3816 
3817     for (int i = 0; i < p_rsp->num_attrs; i++) {
3818       p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
3819       /* Todo. Legth limit check to include null */
3820       if (p_rsp->p_attrs[i].name.str_len && p_rsp->p_attrs[i].name.p_str) {
3821         memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str,
3822                p_rsp->p_attrs[i].name.str_len);
3823         osi_free_and_reset((void**)&p_rsp->p_attrs[i].name.p_str);
3824       }
3825     }
3826     do_in_jni_thread(FROM_HERE,
3827                      base::Bind(bt_rc_ctrl_callbacks->track_changed_cb,
3828                                 p_dev->rc_addr, p_rsp->num_attrs, p_attr));
3829     do_in_jni_thread(FROM_HERE, base::Bind(osi_free, p_attr));
3830   } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
3831     /* Retry for timeout case, this covers error handling
3832      * for continuation failure also.
3833      */
3834     uint32_t attr_list[] = {
3835         AVRC_MEDIA_ATTR_ID_TITLE,       AVRC_MEDIA_ATTR_ID_ARTIST,
3836         AVRC_MEDIA_ATTR_ID_ALBUM,       AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3837         AVRC_MEDIA_ATTR_ID_NUM_TRACKS,  AVRC_MEDIA_ATTR_ID_GENRE,
3838         AVRC_MEDIA_ATTR_ID_PLAYING_TIME};
3839     get_element_attribute_cmd(AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list, p_dev);
3840   } else {
3841     BTIF_TRACE_ERROR("%s: Error in get element attr procedure: %d", __func__,
3842                      p_rsp->status);
3843   }
3844 }
3845 
3846 /***************************************************************************
3847  *
3848  * Function         handle_get_playstatus_response
3849  *
3850  * Description      handles the the play status response, calls
3851  *                  HAL callback to update play position.
3852  * Returns          None
3853  *
3854  **************************************************************************/
handle_get_playstatus_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_PLAY_STATUS_RSP * p_rsp)3855 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
3856                                            tAVRC_GET_PLAY_STATUS_RSP* p_rsp) {
3857 
3858   btif_rc_device_cb_t* p_dev =
3859       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3860 
3861   if (p_dev == NULL) {
3862     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3863     return;
3864   }
3865 
3866 
3867   if (p_rsp->status == AVRC_STS_NO_ERROR) {
3868     do_in_jni_thread(
3869         FROM_HERE,
3870         base::Bind(bt_rc_ctrl_callbacks->play_position_changed_cb,
3871                    p_dev->rc_addr, p_rsp->song_len, p_rsp->song_pos));
3872   } else {
3873     BTIF_TRACE_ERROR("%s: Error in get play status procedure: %d", __func__,
3874                      p_rsp->status);
3875   }
3876 }
3877 
3878 /***************************************************************************
3879  *
3880  * Function         handle_set_addressed_player_response
3881  *
3882  * Description      handles the the set addressed player response, calls
3883  *                  HAL callback
3884  * Returns          None
3885  *
3886  **************************************************************************/
handle_set_addressed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP * p_rsp)3887 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg,
3888                                                  tAVRC_RSP* p_rsp) {
3889 
3890   btif_rc_device_cb_t* p_dev =
3891       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3892 
3893   if (p_dev == NULL) {
3894     BTIF_TRACE_ERROR("%s: p_dev NULL", __func__);
3895     return;
3896   }
3897 
3898 
3899   if (p_rsp->status == AVRC_STS_NO_ERROR) {
3900     do_in_jni_thread(FROM_HERE,
3901                      base::Bind(bt_rc_ctrl_callbacks->set_addressed_player_cb,
3902                                 p_dev->rc_addr, p_rsp->status));
3903   } else {
3904     BTIF_TRACE_ERROR("%s: Error in get play status procedure %d", __func__,
3905                      p_rsp->status);
3906   }
3907 }
3908 
3909 /***************************************************************************
3910  *
3911  * Function         handle_get_folder_items_response
3912  *
3913  * Description      handles the the get folder items response, calls
3914  *                  HAL callback to send the folder items.
3915  * Returns          None
3916  *
3917  **************************************************************************/
handle_get_folder_items_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ITEMS_RSP * p_rsp)3918 static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg,
3919                                              tAVRC_GET_ITEMS_RSP* p_rsp) {
3920   btif_rc_device_cb_t* p_dev =
3921       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
3922 
3923   if (p_rsp->status == AVRC_STS_NO_ERROR) {
3924     /* Convert the internal folder listing into a response that can
3925      * be passed onto JNI via HAL_CBACK
3926      */
3927     uint8_t item_count = p_rsp->item_count;
3928     btrc_folder_items_t* btrc_items = (btrc_folder_items_t*)osi_malloc(
3929         sizeof(btrc_folder_items_t) * item_count);
3930     for (uint8_t i = 0; i < item_count; i++) {
3931       const tAVRC_ITEM* avrc_item = &(p_rsp->p_item_list[i]);
3932       btrc_folder_items_t* btrc_item = &(btrc_items[i]);
3933       BTIF_TRACE_DEBUG("%s folder item type %d", __func__,
3934                        avrc_item->item_type);
3935       switch (avrc_item->item_type) {
3936         case AVRC_ITEM_MEDIA:
3937           BTIF_TRACE_DEBUG("%s setting type to %d", __func__, BTRC_ITEM_MEDIA);
3938           /* Allocate Space for Attributes */
3939           btrc_item->media.num_attrs = avrc_item->u.media.attr_count;
3940           btrc_item->media.p_attrs = (btrc_element_attr_val_t*)osi_malloc(
3941               btrc_item->media.num_attrs * sizeof(btrc_element_attr_val_t));
3942           get_folder_item_type_media(avrc_item, btrc_item);
3943           break;
3944 
3945         case AVRC_ITEM_FOLDER:
3946           BTIF_TRACE_DEBUG("%s setting type to BTRC_ITEM_FOLDER", __func__);
3947           get_folder_item_type_folder(avrc_item, btrc_item);
3948           break;
3949 
3950         case AVRC_ITEM_PLAYER:
3951           BTIF_TRACE_DEBUG("%s setting type to BTRC_ITEM_PLAYER", __func__);
3952           get_folder_item_type_player(avrc_item, btrc_item);
3953           break;
3954 
3955         default:
3956           BTIF_TRACE_ERROR("%s cannot understand folder item type %d", __func__,
3957                            avrc_item->item_type);
3958       }
3959     }
3960 
3961     do_in_jni_thread(
3962         FROM_HERE,
3963         base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
3964                    BTRC_STS_NO_ERROR,
3965                    /* We want to make the ownership explicit in native */
3966                    btrc_items, item_count));
3967 
3968     /* Release the memory block for items and attributes allocated here.
3969      * Since the executor for do_in_jni_thread is a Single Thread Task Runner it
3970      * is okay to queue up the cleanup of btrc_items */
3971     do_in_jni_thread(FROM_HERE, base::Bind(cleanup_btrc_folder_items,
3972                                            btrc_items, item_count));
3973 
3974     BTIF_TRACE_DEBUG("%s get_folder_items_cb sent to JNI thread", __func__);
3975   } else {
3976     BTIF_TRACE_ERROR("%s: Error %d", __func__, p_rsp->status);
3977     do_in_jni_thread(
3978         FROM_HERE,
3979         base::Bind(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
3980                    (btrc_status_t)p_rsp->status, nullptr, 0));
3981   }
3982 }
3983 /***************************************************************************
3984  *
3985  * Function         cleanup_btrc_folder_items
3986  *
3987  * Description      Frees the memory that was allocated for a list of folder
3988  *                  items.
3989  * Returns          None
3990  **************************************************************************/
cleanup_btrc_folder_items(btrc_folder_items_t * btrc_items,uint8_t item_count)3991 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items,
3992                                       uint8_t item_count) {
3993   for (uint8_t i = 0; i < item_count; i++) {
3994     btrc_folder_items_t* btrc_item = &(btrc_items[i]);
3995     switch (btrc_item->item_type) {
3996       case BTRC_ITEM_MEDIA:
3997         osi_free(btrc_item->media.p_attrs);
3998         break;
3999       case BTRC_ITEM_PLAYER:
4000       case BTRC_ITEM_FOLDER:
4001         /*Nothing to free*/
4002         break;
4003       default:
4004         BTIF_TRACE_WARNING("%s free unspecified type", __func__);
4005     }
4006   }
4007   osi_free(btrc_items);
4008 }
4009 
4010 /***************************************************************************
4011  *
4012  * Function         get_folder_item_type_media
4013  *
4014  * Description      Converts the AVRC representation of a folder item with
4015  *                  TYPE media to BTIF representation.
4016  * Returns          None
4017  *
4018  **************************************************************************/
get_folder_item_type_media(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)4019 void get_folder_item_type_media(const tAVRC_ITEM* avrc_item,
4020                                 btrc_folder_items_t* btrc_item) {
4021   btrc_item->item_type = BTRC_ITEM_MEDIA;
4022   const tAVRC_ITEM_MEDIA* avrc_item_media = &(avrc_item->u.media);
4023   btrc_item_media_t* btrc_item_media = &(btrc_item->media);
4024   /* UID */
4025   memset(btrc_item_media->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
4026   memcpy(btrc_item_media->uid, avrc_item_media->uid,
4027          sizeof(uint8_t) * BTRC_UID_SIZE);
4028 
4029   /* Audio/Video type */
4030   switch (avrc_item_media->type) {
4031     case AVRC_MEDIA_TYPE_AUDIO:
4032       btrc_item_media->type = BTRC_MEDIA_TYPE_AUDIO;
4033       break;
4034     case AVRC_MEDIA_TYPE_VIDEO:
4035       btrc_item_media->type = BTRC_MEDIA_TYPE_VIDEO;
4036       break;
4037   }
4038 
4039   /* Charset ID */
4040   btrc_item_media->charset_id = avrc_item_media->name.charset_id;
4041 
4042   /* Copy the name */
4043   BTIF_TRACE_DEBUG("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN,
4044                    avrc_item_media->name.str_len);
4045   memset(btrc_item_media->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
4046   memcpy(btrc_item_media->name, avrc_item_media->name.p_str,
4047          sizeof(uint8_t) * (avrc_item_media->name.str_len));
4048 
4049   /* Extract each attribute */
4050   for (int i = 0; i < avrc_item_media->attr_count; i++) {
4051     btrc_element_attr_val_t* btrc_attr_pair = &(btrc_item_media->p_attrs[i]);
4052     tAVRC_ATTR_ENTRY* avrc_attr_pair = &(avrc_item_media->p_attr_list[i]);
4053 
4054     BTIF_TRACE_DEBUG("%s media attr id 0x%x", __func__,
4055                      avrc_attr_pair->attr_id);
4056 
4057     switch (avrc_attr_pair->attr_id) {
4058       case AVRC_MEDIA_ATTR_ID_TITLE:
4059         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TITLE;
4060         break;
4061       case AVRC_MEDIA_ATTR_ID_ARTIST:
4062         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ARTIST;
4063         break;
4064       case AVRC_MEDIA_ATTR_ID_ALBUM:
4065         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ALBUM;
4066         break;
4067       case AVRC_MEDIA_ATTR_ID_TRACK_NUM:
4068         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TRACK_NUM;
4069         break;
4070       case AVRC_MEDIA_ATTR_ID_NUM_TRACKS:
4071         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_NUM_TRACKS;
4072         break;
4073       case AVRC_MEDIA_ATTR_ID_GENRE:
4074         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_GENRE;
4075         break;
4076       case AVRC_MEDIA_ATTR_ID_PLAYING_TIME:
4077         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_PLAYING_TIME;
4078         break;
4079       default:
4080         BTIF_TRACE_ERROR("%s invalid media attr id: 0x%x", __func__,
4081                          avrc_attr_pair->attr_id);
4082         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_INVALID;
4083     }
4084 
4085     memset(btrc_attr_pair->text, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
4086     memcpy(btrc_attr_pair->text, avrc_attr_pair->name.p_str,
4087            avrc_attr_pair->name.str_len);
4088   }
4089 }
4090 
4091 /***************************************************************************
4092  *
4093  * Function         get_folder_item_type_folder
4094  *
4095  * Description      Converts the AVRC representation of a folder item with
4096  *                  TYPE folder to BTIF representation.
4097  * Returns          None
4098  *
4099  **************************************************************************/
get_folder_item_type_folder(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)4100 void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
4101                                  btrc_folder_items_t* btrc_item) {
4102   btrc_item->item_type = BTRC_ITEM_FOLDER;
4103   const tAVRC_ITEM_FOLDER* avrc_item_folder = &(avrc_item->u.folder);
4104   btrc_item_folder_t* btrc_item_folder = &(btrc_item->folder);
4105   /* Copy the UID */
4106   memset(btrc_item_folder->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
4107   memcpy(btrc_item_folder->uid, avrc_item_folder->uid,
4108          sizeof(uint8_t) * BTRC_UID_SIZE);
4109 
4110   /* Copy the type */
4111   switch (avrc_item_folder->type) {
4112     case AVRC_FOLDER_TYPE_MIXED:
4113       btrc_item_folder->type = BTRC_FOLDER_TYPE_MIXED;
4114       break;
4115     case AVRC_FOLDER_TYPE_TITLES:
4116       btrc_item_folder->type = BTRC_FOLDER_TYPE_TITLES;
4117       break;
4118     case AVRC_FOLDER_TYPE_ALNUMS:
4119       btrc_item_folder->type = BTRC_FOLDER_TYPE_ALBUMS;
4120       break;
4121     case AVRC_FOLDER_TYPE_ARTISTS:
4122       btrc_item_folder->type = BTRC_FOLDER_TYPE_ARTISTS;
4123       break;
4124     case AVRC_FOLDER_TYPE_GENRES:
4125       btrc_item_folder->type = BTRC_FOLDER_TYPE_GENRES;
4126       break;
4127     case AVRC_FOLDER_TYPE_PLAYLISTS:
4128       btrc_item_folder->type = BTRC_FOLDER_TYPE_PLAYLISTS;
4129       break;
4130     case AVRC_FOLDER_TYPE_YEARS:
4131       btrc_item_folder->type = BTRC_FOLDER_TYPE_YEARS;
4132       break;
4133   }
4134 
4135   /* Copy if playable */
4136   btrc_item_folder->playable = avrc_item_folder->playable;
4137 
4138   /* Copy name */
4139   BTIF_TRACE_DEBUG("%s max len %d str len %d", __func__, BTRC_MAX_ATTR_STR_LEN,
4140                    avrc_item_folder->name.str_len);
4141   memset(btrc_item_folder->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
4142   memcpy(btrc_item_folder->name, avrc_item_folder->name.p_str,
4143          avrc_item_folder->name.str_len * sizeof(uint8_t));
4144 
4145   /* Copy charset */
4146   btrc_item_folder->charset_id = avrc_item_folder->name.charset_id;
4147 }
4148 
4149 /***************************************************************************
4150  *
4151  * Function         get_folder_item_type_player
4152  *
4153  * Description      Converts the AVRC representation of a folder item with
4154  *                  TYPE player to BTIF representation.
4155  * Returns          None
4156  *
4157  **************************************************************************/
get_folder_item_type_player(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)4158 void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
4159                                  btrc_folder_items_t* btrc_item) {
4160   btrc_item->item_type = BTRC_ITEM_PLAYER;
4161   const tAVRC_ITEM_PLAYER* avrc_item_player = &(avrc_item->u.player);
4162   btrc_item_player_t* btrc_item_player = &(btrc_item->player);
4163   /* Player ID */
4164   btrc_item_player->player_id = avrc_item_player->player_id;
4165   /* Major type */
4166   btrc_item_player->major_type = avrc_item_player->major_type;
4167   /* Sub type */
4168   btrc_item_player->sub_type = avrc_item_player->sub_type;
4169   /* Play status */
4170   btrc_item_player->play_status = avrc_item_player->play_status;
4171   /* Features */
4172   memcpy(btrc_item_player->features, avrc_item_player->features,
4173          BTRC_FEATURE_BIT_MASK_SIZE);
4174 
4175   memset(btrc_item_player->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
4176   memcpy(btrc_item_player->name, avrc_item_player->name.p_str,
4177          avrc_item_player->name.str_len);
4178 }
4179 
4180 /***************************************************************************
4181  *
4182  * Function         handle_change_path_response
4183  *
4184  * Description      handles the the change path response, calls
4185  *                  HAL callback to send the updated folder
4186  * Returns          None
4187  *
4188  **************************************************************************/
handle_change_path_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_CHG_PATH_RSP * p_rsp)4189 static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg,
4190                                         tAVRC_CHG_PATH_RSP* p_rsp) {
4191   btif_rc_device_cb_t* p_dev =
4192       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
4193 
4194   if (p_rsp->status == AVRC_STS_NO_ERROR) {
4195     do_in_jni_thread(FROM_HERE,
4196                      base::Bind(bt_rc_ctrl_callbacks->change_folder_path_cb,
4197                                 p_dev->rc_addr, p_rsp->num_items));
4198   } else {
4199     BTIF_TRACE_ERROR("%s error in handle_change_path_response %d", __func__,
4200                      p_rsp->status);
4201   }
4202 }
4203 
4204 /***************************************************************************
4205  *
4206  * Function         handle_set_browsed_player_response
4207  *
4208  * Description      handles the the change path response, calls
4209  *                  HAL callback to send the updated folder
4210  * Returns          None
4211  *
4212  **************************************************************************/
handle_set_browsed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_SET_BR_PLAYER_RSP * p_rsp)4213 static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg,
4214                                                tAVRC_SET_BR_PLAYER_RSP* p_rsp) {
4215   btif_rc_device_cb_t* p_dev =
4216       btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
4217 
4218   if (p_rsp->status == AVRC_STS_NO_ERROR) {
4219     do_in_jni_thread(
4220         FROM_HERE,
4221         base::Bind(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr,
4222                    p_rsp->num_items, p_rsp->folder_depth));
4223   } else {
4224     BTIF_TRACE_ERROR("%s error %d", __func__, p_rsp->status);
4225   }
4226 }
4227 
4228 /***************************************************************************
4229  *
4230  * Function         clear_cmd_timeout
4231  *
4232  * Description      helper function to stop the command timeout timer
4233  * Returns          None
4234  *
4235  **************************************************************************/
clear_cmd_timeout(uint8_t label)4236 static void clear_cmd_timeout(uint8_t label) {
4237   rc_transaction_t* p_txn;
4238 
4239   p_txn = get_transaction_by_lbl(label);
4240   if (p_txn == NULL) {
4241     BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __func__);
4242     return;
4243   }
4244 
4245   if (p_txn->txn_timer != NULL) alarm_cancel(p_txn->txn_timer);
4246 }
4247 
4248 /***************************************************************************
4249  *
4250  * Function         handle_avk_rc_metamsg_rsp
4251  *
4252  * Description      Handle RC metamessage response
4253  *
4254  * Returns          void
4255  *
4256  **************************************************************************/
handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG * pmeta_msg)4257 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) {
4258   tAVRC_RESPONSE avrc_response = {0};
4259   uint8_t scratch_buf[512] = {0};  // this variable is unused
4260   uint16_t buf_len;
4261   tAVRC_STS status;
4262 
4263   BTIF_TRACE_DEBUG("%s: opcode: %d rsp_code: %d  ", __func__,
4264                    pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
4265 
4266   status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf,
4267                                   &buf_len);
4268   if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) &&
4269       (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) &&
4270       (pmeta_msg->code <= AVRC_RSP_INTERIM)) {
4271     BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d", __func__,
4272                      status, avrc_response.pdu,
4273                      pmeta_msg->p_msg->vendor.hdr.ctype);
4274 
4275     switch (avrc_response.pdu) {
4276       case AVRC_PDU_REGISTER_NOTIFICATION:
4277         handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
4278         if (pmeta_msg->code == AVRC_RSP_INTERIM) {
4279           /* Don't free the transaction Id */
4280           clear_cmd_timeout(pmeta_msg->label);
4281           return;
4282         }
4283         break;
4284 
4285       case AVRC_PDU_GET_CAPABILITIES:
4286         handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
4287         break;
4288 
4289       case AVRC_PDU_LIST_PLAYER_APP_ATTR:
4290         handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
4291         break;
4292 
4293       case AVRC_PDU_LIST_PLAYER_APP_VALUES:
4294         handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
4295         break;
4296 
4297       case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
4298         handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
4299         break;
4300 
4301       case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
4302         handle_app_attr_txt_response(pmeta_msg,
4303                                      &avrc_response.get_app_attr_txt);
4304         break;
4305 
4306       case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
4307         handle_app_attr_val_txt_response(pmeta_msg,
4308                                          &avrc_response.get_app_val_txt);
4309         break;
4310 
4311       case AVRC_PDU_SET_PLAYER_APP_VALUE:
4312         handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
4313         break;
4314 
4315       case AVRC_PDU_GET_ELEMENT_ATTR:
4316         handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_attrs);
4317         break;
4318 
4319       case AVRC_PDU_GET_PLAY_STATUS:
4320         handle_get_playstatus_response(pmeta_msg,
4321                                        &avrc_response.get_play_status);
4322         break;
4323 
4324       case AVRC_PDU_SET_ADDRESSED_PLAYER:
4325         handle_set_addressed_player_response(pmeta_msg, &avrc_response.rsp);
4326         break;
4327     }
4328   } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) {
4329     BTIF_TRACE_DEBUG("%s AVRC_OP_BROWSE pdu %d", __func__, avrc_response.pdu);
4330     /* check what kind of command it is for browsing */
4331     switch (avrc_response.pdu) {
4332       case AVRC_PDU_GET_FOLDER_ITEMS:
4333         handle_get_folder_items_response(pmeta_msg, &avrc_response.get_items);
4334         break;
4335       case AVRC_PDU_CHANGE_PATH:
4336         handle_change_path_response(pmeta_msg, &avrc_response.chg_path);
4337         break;
4338       case AVRC_PDU_SET_BROWSED_PLAYER:
4339         handle_set_browsed_player_response(pmeta_msg, &avrc_response.br_player);
4340         break;
4341       default:
4342         BTIF_TRACE_ERROR("%s cannot handle browse pdu %d", __func__,
4343                          pmeta_msg->p_msg->hdr.opcode);
4344     }
4345   } else {
4346     BTIF_TRACE_DEBUG(
4347         "%s: Invalid Vendor Command code: %d len: %d. Not processing it.",
4348         __func__, pmeta_msg->code, pmeta_msg->len);
4349     return;
4350   }
4351   BTIF_TRACE_DEBUG("XX __func__ release transaction %d", pmeta_msg->label);
4352   release_transaction(pmeta_msg->label);
4353 }
4354 
4355 /***************************************************************************
4356  *
4357  * Function         handle_avk_rc_metamsg_cmd
4358  *
4359  * Description      Handle RC metamessage response
4360  *
4361  * Returns          void
4362  *
4363  **************************************************************************/
handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG * pmeta_msg)4364 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) {
4365   tAVRC_COMMAND avrc_cmd = {0};
4366   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
4367   btif_rc_device_cb_t* p_dev = NULL;
4368 
4369   BTIF_TRACE_DEBUG("%s: opcode: %d rsp_code: %d", __func__,
4370                    pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
4371   status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
4372   if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) &&
4373       (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) {
4374     BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
4375                      __func__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
4376 
4377     if (status != AVRC_STS_NO_ERROR) {
4378       /* return error */
4379       BTIF_TRACE_WARNING(
4380           "%s: Error in parsing received metamsg command. status: 0x%02x",
4381           __func__, status);
4382       send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu,
4383                            status, pmeta_msg->p_msg->hdr.opcode);
4384     } else {
4385       p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
4386       if (p_dev == NULL) {
4387         BTIF_TRACE_ERROR("%s: avk rc meta msg cmd for Invalid rc handle",
4388                          __func__);
4389         return;
4390       }
4391 
4392       if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
4393         uint8_t event_id = avrc_cmd.reg_notif.event_id;
4394         BTIF_TRACE_EVENT("%s: Register notification event_id: %s", __func__,
4395                          dump_rc_notification_event_id(event_id));
4396       } else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) {
4397         BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __func__);
4398       }
4399 
4400       btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label,
4401                                      p_dev);
4402     }
4403   } else {
4404     BTIF_TRACE_DEBUG(
4405         "%s: Invalid Vendor Command  code: %d len: %d. Not processing it.",
4406         __func__, pmeta_msg->code, pmeta_msg->len);
4407     return;
4408   }
4409 }
4410 
4411 /***************************************************************************
4412  *
4413  * Function         cleanup
4414  *
4415  * Description      Closes the AVRC interface
4416  *
4417  * Returns          void
4418  *
4419  **************************************************************************/
cleanup()4420 static void cleanup() {
4421   BTIF_TRACE_EVENT("%s: ", __func__);
4422   if (bt_rc_callbacks) {
4423     bt_rc_callbacks = NULL;
4424   }
4425 
4426   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
4427     alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer);
4428     memset(&btif_rc_cb.rc_multi_cb[idx], 0,
4429            sizeof(btif_rc_cb.rc_multi_cb[idx]));
4430   }
4431 
4432   BTIF_TRACE_EVENT("%s: completed", __func__);
4433 }
4434 
4435 /***************************************************************************
4436  *
4437  * Function         cleanup_ctrl
4438  *
4439  * Description      Closes the AVRC Controller interface
4440  *
4441  * Returns          void
4442  *
4443  **************************************************************************/
cleanup_ctrl()4444 static void cleanup_ctrl() {
4445   BTIF_TRACE_EVENT("%s: ", __func__);
4446 
4447   if (bt_rc_ctrl_callbacks) {
4448     bt_rc_ctrl_callbacks = NULL;
4449   }
4450 
4451   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
4452     alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer);
4453     memset(&btif_rc_cb.rc_multi_cb[idx], 0,
4454            sizeof(btif_rc_cb.rc_multi_cb[idx]));
4455   }
4456 
4457   memset(&btif_rc_cb.rc_multi_cb, 0, sizeof(btif_rc_cb.rc_multi_cb));
4458   BTIF_TRACE_EVENT("%s: completed", __func__);
4459 }
4460 
4461 /***************************************************************************
4462  *
4463  * Function         getcapabilities_cmd
4464  *
4465  * Description      GetCapabilties from Remote(Company_ID, Events_Supported)
4466  *
4467  * Returns          void
4468  *
4469  **************************************************************************/
getcapabilities_cmd(uint8_t cap_id,btif_rc_device_cb_t * p_dev)4470 static bt_status_t getcapabilities_cmd(uint8_t cap_id,
4471                                        btif_rc_device_cb_t* p_dev) {
4472   BTIF_TRACE_DEBUG("%s: cap_id: %d", __func__, cap_id);
4473   CHECK_RC_CONNECTED(p_dev);
4474 
4475   tAVRC_COMMAND avrc_cmd = {0};
4476   avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
4477   avrc_cmd.get_caps.capability_id = cap_id;
4478   avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
4479   avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
4480 
4481   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4482 }
4483 
4484 /***************************************************************************
4485  *
4486  * Function         list_player_app_setting_attrib_cmd
4487  *
4488  * Description      Get supported List Player Attributes
4489  *
4490  * Returns          void
4491  *
4492  **************************************************************************/
list_player_app_setting_attrib_cmd(btif_rc_device_cb_t * p_dev)4493 static bt_status_t list_player_app_setting_attrib_cmd(
4494     btif_rc_device_cb_t* p_dev) {
4495   BTIF_TRACE_DEBUG("%s", __func__);
4496   CHECK_RC_CONNECTED(p_dev);
4497 
4498   tAVRC_COMMAND avrc_cmd = {0};
4499   avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
4500   avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
4501   avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
4502 
4503   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4504 }
4505 
4506 /***************************************************************************
4507  *
4508  * Function         list_player_app_setting_value_cmd
4509  *
4510  * Description      Get values of supported Player Attributes
4511  *
4512  * Returns          void
4513  *
4514  **************************************************************************/
list_player_app_setting_value_cmd(uint8_t attrib_id,btif_rc_device_cb_t * p_dev)4515 static bt_status_t list_player_app_setting_value_cmd(
4516     uint8_t attrib_id, btif_rc_device_cb_t* p_dev) {
4517   BTIF_TRACE_DEBUG("%s: attrib_id: %d", __func__, attrib_id);
4518   CHECK_RC_CONNECTED(p_dev);
4519 
4520   tAVRC_COMMAND avrc_cmd = {0};
4521   avrc_cmd.list_app_values.attr_id = attrib_id;
4522   avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
4523   avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
4524   avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
4525 
4526   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4527 }
4528 
4529 /***************************************************************************
4530  *
4531  * Function         get_player_app_setting_cmd
4532  *
4533  * Description      Get current values of Player Attributes
4534  *
4535  * Returns          void
4536  *
4537  **************************************************************************/
get_player_app_setting_cmd(uint8_t num_attrib,uint8_t * attrib_ids,btif_rc_device_cb_t * p_dev)4538 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib,
4539                                               uint8_t* attrib_ids,
4540                                               btif_rc_device_cb_t* p_dev) {
4541   BTIF_TRACE_DEBUG("%s: num_attrib: %d", __func__, num_attrib);
4542   CHECK_RC_CONNECTED(p_dev);
4543 
4544   tAVRC_COMMAND avrc_cmd = {0};
4545   avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
4546   avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
4547   avrc_cmd.get_cur_app_val.num_attr = num_attrib;
4548   avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
4549 
4550   for (int count = 0; count < num_attrib; count++) {
4551     avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
4552   }
4553 
4554   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4555 }
4556 
4557 /***************************************************************************
4558  *
4559  * Function         get_playback_state_cmd
4560  *
4561  * Description      Fetch the current playback state for the device
4562  *
4563  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4564  *                  BT_STATUS_FAIL.
4565  *
4566  **************************************************************************/
get_playback_state_cmd(const RawAddress & bd_addr)4567 static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) {
4568   BTIF_TRACE_DEBUG("%s", __func__);
4569   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4570   return get_play_status_cmd(p_dev);
4571 }
4572 
4573 /***************************************************************************
4574  *
4575  * Function         get_now_playing_list_cmd
4576  *
4577  * Description      Fetch the now playing list
4578  *
4579  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
4580  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
4581  *
4582  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4583  *                  BT_STATUS_FAIL.
4584  *
4585  **************************************************************************/
get_now_playing_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)4586 static bt_status_t get_now_playing_list_cmd(const RawAddress& bd_addr,
4587                                             uint32_t start_item,
4588                                             uint32_t end_item) {
4589   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item);
4590   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_NOW_PLAYING, start_item,
4591                               end_item);
4592 }
4593 
4594 /***************************************************************************
4595  *
4596  * Function         get_folder_list_cmd
4597  *
4598  * Description      Fetch the currently selected folder list
4599  *
4600  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
4601  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
4602  *
4603  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4604  *                  BT_STATUS_FAIL.
4605  *
4606  **************************************************************************/
get_folder_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)4607 static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr,
4608                                        uint32_t start_item, uint32_t end_item) {
4609   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item);
4610   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item,
4611                               end_item);
4612 }
4613 
4614 /***************************************************************************
4615  *
4616  * Function         get_player_list_cmd
4617  *
4618  * Description      Fetch the player list
4619  *
4620  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
4621  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
4622  *
4623  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4624  *                  BT_STATUS_FAIL.
4625  *
4626  **************************************************************************/
get_player_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)4627 static bt_status_t get_player_list_cmd(const RawAddress& bd_addr,
4628                                        uint32_t start_item, uint32_t end_item) {
4629   BTIF_TRACE_DEBUG("%s start, end: (%d, %d)", __func__, start_item, end_item);
4630   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item,
4631                               end_item);
4632 }
4633 
4634 /***************************************************************************
4635  *
4636  * Function         change_folder_path_cmd
4637  *
4638  * Description      Change the folder.
4639  *
4640  * Paramters        direction: Direction (Up/Down) to change folder
4641  *                  uid: The UID of folder to move to
4642  *                  start_item: First item to fetch (0 to fetch from beganning)
4643  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
4644  *
4645  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4646  *                  BT_STATUS_FAIL.
4647  *
4648  **************************************************************************/
change_folder_path_cmd(const RawAddress & bd_addr,uint8_t direction,uint8_t * uid)4649 static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr,
4650                                           uint8_t direction, uint8_t* uid) {
4651   BTIF_TRACE_DEBUG("%s: direction %d", __func__, direction);
4652   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4653   CHECK_RC_CONNECTED(p_dev);
4654   CHECK_BR_CONNECTED(p_dev);
4655 
4656   tAVRC_COMMAND avrc_cmd = {0};
4657 
4658   avrc_cmd.chg_path.pdu = AVRC_PDU_CHANGE_PATH;
4659   avrc_cmd.chg_path.status = AVRC_STS_NO_ERROR;
4660   // TODO(sanketa): Improve for database aware clients.
4661   avrc_cmd.chg_path.uid_counter = 0;
4662   avrc_cmd.chg_path.direction = direction;
4663 
4664   memset(avrc_cmd.chg_path.folder_uid, 0, AVRC_UID_SIZE * sizeof(uint8_t));
4665   memcpy(avrc_cmd.chg_path.folder_uid, uid, AVRC_UID_SIZE * sizeof(uint8_t));
4666 
4667   BT_HDR* p_msg = NULL;
4668   tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg);
4669   if (status != AVRC_STS_NO_ERROR) {
4670     BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status);
4671     return BT_STATUS_FAIL;
4672   }
4673 
4674   rc_transaction_t* p_transaction = NULL;
4675   bt_status_t tran_status = get_transaction(&p_transaction);
4676   if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
4677     osi_free(p_msg);
4678     BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
4679                      __func__, tran_status);
4680     return BT_STATUS_FAIL;
4681   }
4682 
4683   BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__,
4684                    p_transaction->lbl);
4685   BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
4686   return BT_STATUS_SUCCESS;
4687 }
4688 
4689 /***************************************************************************
4690  *
4691  * Function         set_browsed_player_cmd
4692  *
4693  * Description      Change the browsed player.
4694  *
4695  * Paramters        id: The UID of player to move to
4696  *
4697  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4698  *                  BT_STATUS_FAIL.
4699  *
4700  **************************************************************************/
set_browsed_player_cmd(const RawAddress & bd_addr,uint16_t id)4701 static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr,
4702                                           uint16_t id) {
4703   BTIF_TRACE_DEBUG("%s: id %d", __func__, id);
4704   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4705   CHECK_RC_CONNECTED(p_dev);
4706   CHECK_BR_CONNECTED(p_dev);
4707 
4708   rc_transaction_t* p_transaction = NULL;
4709 
4710   tAVRC_COMMAND avrc_cmd = {0};
4711   avrc_cmd.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER;
4712   avrc_cmd.br_player.status = AVRC_STS_NO_ERROR;
4713   // TODO(sanketa): Improve for database aware clients.
4714   avrc_cmd.br_player.player_id = id;
4715 
4716   BT_HDR* p_msg = NULL;
4717   tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg);
4718   if (status != AVRC_STS_NO_ERROR) {
4719     BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status);
4720     return BT_STATUS_FAIL;
4721   }
4722 
4723   bt_status_t tran_status = get_transaction(&p_transaction);
4724   if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
4725     osi_free(p_msg);
4726     BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
4727                      __func__, tran_status);
4728     return BT_STATUS_FAIL;
4729   }
4730 
4731   BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__,
4732                    p_transaction->lbl);
4733   BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
4734   return BT_STATUS_SUCCESS;
4735 }
4736 
4737 /***************************************************************************
4738  **
4739  ** Function         set_addressed_player_cmd
4740  **
4741  ** Description      Change the addressed player.
4742  **
4743  ** Paramters        id: The UID of player to move to
4744  **
4745  ** Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4746  **                  BT_STATUS_FAIL.
4747  **
4748  ***************************************************************************/
set_addressed_player_cmd(const RawAddress & bd_addr,uint16_t id)4749 static bt_status_t set_addressed_player_cmd(const RawAddress& bd_addr,
4750                                             uint16_t id) {
4751   BTIF_TRACE_DEBUG("%s: id %d", __func__, id);
4752 
4753   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4754   CHECK_RC_CONNECTED(p_dev);
4755   CHECK_BR_CONNECTED(p_dev);
4756 
4757   tAVRC_COMMAND avrc_cmd = {0};
4758   BT_HDR* p_msg = NULL;
4759 
4760   avrc_cmd.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER;
4761   avrc_cmd.addr_player.status = AVRC_STS_NO_ERROR;
4762   // TODO(sanketa): Improve for database aware clients.
4763   avrc_cmd.addr_player.player_id = id;
4764 
4765   tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg);
4766   if (status != AVRC_STS_NO_ERROR) {
4767     BTIF_TRACE_ERROR("%s: failed to build command status %d", __func__, status);
4768     return BT_STATUS_FAIL;
4769   }
4770 
4771   rc_transaction_t* p_transaction = NULL;
4772   bt_status_t tran_status = get_transaction(&p_transaction);
4773 
4774   if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
4775     osi_free(p_msg);
4776     BTIF_TRACE_ERROR("%s: failed to obtain txn details. status: 0x%02x",
4777                      __func__, tran_status);
4778     return BT_STATUS_FAIL;
4779   }
4780 
4781   BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__,
4782                    p_transaction->lbl);
4783   BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
4784   return BT_STATUS_SUCCESS;
4785 }
4786 
4787 /***************************************************************************
4788  *
4789  * Function         get_folder_items_cmd
4790  *
4791  * Description      Helper function to browse the content hierarchy of the
4792  *                  TG device.
4793  *
4794  * Paramters        scope: AVRC_SCOPE_NOW_PLAYING (etc) for various browseable
4795  *                  content
4796  *                  start_item: First item to fetch (0 to fetch from beganning)
4797  *                  end_item: Last item to fetch (0xffff to fetch until end)
4798  *
4799  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
4800  *                  BT_STATUS_FAIL.
4801  *
4802  **************************************************************************/
get_folder_items_cmd(const RawAddress & bd_addr,uint8_t scope,uint32_t start_item,uint32_t end_item)4803 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr,
4804                                         uint8_t scope, uint32_t start_item,
4805                                         uint32_t end_item) {
4806   /* Check that both avrcp and browse channel are connected. */
4807   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4808   BTIF_TRACE_DEBUG("%s", __func__);
4809   CHECK_RC_CONNECTED(p_dev);
4810   CHECK_BR_CONNECTED(p_dev);
4811 
4812   tAVRC_COMMAND avrc_cmd = {0};
4813 
4814   /* Set the layer specific to point to browse although this should really
4815    * be done by lower layers and looking at the PDU
4816    */
4817   avrc_cmd.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS;
4818   avrc_cmd.get_items.status = AVRC_STS_NO_ERROR;
4819   avrc_cmd.get_items.scope = scope;
4820   avrc_cmd.get_items.start_item = start_item;
4821   avrc_cmd.get_items.end_item = end_item;
4822   avrc_cmd.get_items.attr_count = 0; /* p_attr_list does not matter hence */
4823 
4824   BT_HDR* p_msg = NULL;
4825   tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg);
4826   if (status != AVRC_STS_NO_ERROR) {
4827     BTIF_TRACE_ERROR("%s failed to build command status %d", __func__, status);
4828     return BT_STATUS_FAIL;
4829   }
4830 
4831   rc_transaction_t* p_transaction = NULL;
4832   bt_status_t tran_status = get_transaction(&p_transaction);
4833   if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
4834     osi_free(p_msg);
4835     BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
4836                      __func__, tran_status);
4837     return BT_STATUS_FAIL;
4838   }
4839 
4840   BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d", __func__,
4841                    p_transaction->lbl);
4842   BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
4843   return BT_STATUS_SUCCESS;
4844 }
4845 
4846 /***************************************************************************
4847  *
4848  * Function         change_player_app_setting
4849  *
4850  * Description      Set current values of Player Attributes
4851  *
4852  * Returns          void
4853  *
4854  **************************************************************************/
change_player_app_setting(const RawAddress & bd_addr,uint8_t num_attrib,uint8_t * attrib_ids,uint8_t * attrib_vals)4855 static bt_status_t change_player_app_setting(const RawAddress& bd_addr,
4856                                              uint8_t num_attrib,
4857                                              uint8_t* attrib_ids,
4858                                              uint8_t* attrib_vals) {
4859   BTIF_TRACE_DEBUG("%s: num_attrib: %d", __func__, num_attrib);
4860   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4861   CHECK_RC_CONNECTED(p_dev);
4862 
4863   tAVRC_COMMAND avrc_cmd = {0};
4864   avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
4865   avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
4866   avrc_cmd.set_app_val.num_val = num_attrib;
4867   avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
4868   avrc_cmd.set_app_val.p_vals =
4869       (tAVRC_APP_SETTING*)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
4870   for (int count = 0; count < num_attrib; count++) {
4871     avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
4872     avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
4873   }
4874 
4875   bt_status_t st = build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
4876   osi_free_and_reset((void**)&avrc_cmd.set_app_val.p_vals);
4877   return st;
4878 }
4879 
4880 /***************************************************************************
4881  *
4882  * Function         play_item_cmd
4883  *
4884  * Description      Play the item specified by UID & scope
4885  *
4886  * Returns          void
4887  *
4888  **************************************************************************/
play_item_cmd(const RawAddress & bd_addr,uint8_t scope,uint8_t * uid,uint16_t uid_counter)4889 static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope,
4890                                  uint8_t* uid, uint16_t uid_counter) {
4891   BTIF_TRACE_DEBUG("%s: scope %d uid_counter %d", __func__, scope, uid_counter);
4892   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
4893   CHECK_RC_CONNECTED(p_dev);
4894   CHECK_BR_CONNECTED(p_dev);
4895 
4896   tAVRC_COMMAND avrc_cmd = {0};
4897   avrc_cmd.pdu = AVRC_PDU_PLAY_ITEM;
4898   avrc_cmd.play_item.opcode = AVRC_OP_VENDOR;
4899   avrc_cmd.play_item.status = AVRC_STS_NO_ERROR;
4900   avrc_cmd.play_item.scope = scope;
4901   memcpy(avrc_cmd.play_item.uid, uid, AVRC_UID_SIZE);
4902   avrc_cmd.play_item.uid_counter = uid_counter;
4903 
4904   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
4905 }
4906 
4907 /***************************************************************************
4908  *
4909  * Function         get_player_app_setting_attr_text_cmd
4910  *
4911  * Description      Get text description for app attribute
4912  *
4913  * Returns          void
4914  *
4915  **************************************************************************/
get_player_app_setting_attr_text_cmd(uint8_t * attrs,uint8_t num_attrs,btif_rc_device_cb_t * p_dev)4916 static bt_status_t get_player_app_setting_attr_text_cmd(
4917     uint8_t* attrs, uint8_t num_attrs, btif_rc_device_cb_t* p_dev) {
4918   BTIF_TRACE_DEBUG("%s: num attrs: %d", __func__, num_attrs);
4919   CHECK_RC_CONNECTED(p_dev);
4920 
4921   tAVRC_COMMAND avrc_cmd = {0};
4922   avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
4923   avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
4924   avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
4925 
4926   for (int count = 0; count < num_attrs; count++) {
4927     avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
4928   }
4929 
4930   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4931 }
4932 
4933 /***************************************************************************
4934  *
4935  * Function         get_player_app_setting_val_text_cmd
4936  *
4937  * Description      Get text description for app attribute values
4938  *
4939  * Returns          void
4940  *
4941  **************************************************************************/
get_player_app_setting_value_text_cmd(uint8_t * vals,uint8_t num_vals,btif_rc_device_cb_t * p_dev)4942 static bt_status_t get_player_app_setting_value_text_cmd(
4943     uint8_t* vals, uint8_t num_vals, btif_rc_device_cb_t* p_dev) {
4944   BTIF_TRACE_DEBUG("%s: num_vals: %d", __func__, num_vals);
4945   CHECK_RC_CONNECTED(p_dev);
4946 
4947   tAVRC_COMMAND avrc_cmd = {0};
4948   avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
4949   avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
4950   avrc_cmd.get_app_val_txt.num_val = num_vals;
4951 
4952   for (int count = 0; count < num_vals; count++) {
4953     avrc_cmd.get_app_val_txt.vals[count] = vals[count];
4954   }
4955 
4956   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
4957 }
4958 
4959 /***************************************************************************
4960  *
4961  * Function         register_notification_cmd
4962  *
4963  * Description      Send Command to register for a Notification ID
4964  *
4965  * Returns          void
4966  *
4967  **************************************************************************/
register_notification_cmd(uint8_t label,uint8_t event_id,uint32_t event_value,btif_rc_device_cb_t * p_dev)4968 static bt_status_t register_notification_cmd(uint8_t label, uint8_t event_id,
4969                                              uint32_t event_value,
4970                                              btif_rc_device_cb_t* p_dev) {
4971   BTIF_TRACE_DEBUG("%s: event_id: %d event_value %d", __func__, event_id,
4972                    event_value);
4973   CHECK_RC_CONNECTED(p_dev);
4974 
4975   tAVRC_COMMAND avrc_cmd = {0};
4976   avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
4977   avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
4978   avrc_cmd.reg_notif.event_id = event_id;
4979   avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
4980   avrc_cmd.reg_notif.param = event_value;
4981 
4982   BT_HDR* p_msg = NULL;
4983   tAVRC_STS status = AVRC_BldCommand(&avrc_cmd, &p_msg);
4984   if (status == AVRC_STS_NO_ERROR) {
4985     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
4986     BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__,
4987                      label);
4988     if (p_msg != NULL) {
4989       BTA_AvVendorCmd(p_dev->rc_handle, label, AVRC_CMD_NOTIF, data_start,
4990                       p_msg->len);
4991       status = BT_STATUS_SUCCESS;
4992     }
4993   } else {
4994     BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__,
4995                      status);
4996   }
4997   osi_free(p_msg);
4998   return (bt_status_t)status;
4999 }
5000 
5001 /***************************************************************************
5002  *
5003  * Function         get_element_attribute_cmd
5004  *
5005  * Description      Get Element Attribute for  attributeIds
5006  *
5007  * Returns          void
5008  *
5009  **************************************************************************/
get_element_attribute_cmd(uint8_t num_attribute,uint32_t * p_attr_ids,btif_rc_device_cb_t * p_dev)5010 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute,
5011                                              uint32_t* p_attr_ids,
5012                                              btif_rc_device_cb_t* p_dev) {
5013   BTIF_TRACE_DEBUG("%s: num_attribute: %d attribute_id: %d", __func__,
5014                    num_attribute, p_attr_ids[0]);
5015   CHECK_RC_CONNECTED(p_dev);
5016 
5017   tAVRC_COMMAND avrc_cmd = {0};
5018   avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
5019   avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
5020   avrc_cmd.get_elem_attrs.num_attr = num_attribute;
5021   avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
5022   for (int count = 0; count < num_attribute; count++) {
5023     avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
5024   }
5025 
5026   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
5027 }
5028 
5029 /***************************************************************************
5030  *
5031  * Function         get_play_status_cmd
5032  *
5033  * Description      Get Playing Status of a Device
5034  *
5035  * Returns          bt_status_t
5036  *
5037  **************************************************************************/
get_play_status_cmd(btif_rc_device_cb_t * p_dev)5038 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev) {
5039   BTIF_TRACE_DEBUG("%s", __func__);
5040   CHECK_RC_CONNECTED(p_dev);
5041 
5042   tAVRC_COMMAND avrc_cmd = {0};
5043   avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
5044   avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
5045   avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
5046 
5047   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
5048 }
5049 
5050 /***************************************************************************
5051  *
5052  * Function         set_volume_rsp
5053  *
5054  * Description      Rsp for SetAbsoluteVolume Command
5055  *
5056  * Returns          void
5057  *
5058  **************************************************************************/
set_volume_rsp(const RawAddress & bd_addr,uint8_t abs_vol,uint8_t label)5059 static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol,
5060                                   uint8_t label) {
5061   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
5062   tAVRC_RESPONSE avrc_rsp;
5063   BT_HDR* p_msg = NULL;
5064   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
5065 
5066   CHECK_RC_CONNECTED(p_dev);
5067 
5068   BTIF_TRACE_DEBUG("%s: abs_vol: %d", __func__, abs_vol);
5069 
5070   avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
5071   avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
5072   avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
5073   avrc_rsp.volume.volume = abs_vol;
5074   status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
5075   if (status == AVRC_STS_NO_ERROR) {
5076     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
5077     BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__,
5078                      p_dev->rc_vol_label);
5079     if (p_msg != NULL) {
5080       BTA_AvVendorRsp(p_dev->rc_handle, label, AVRC_RSP_ACCEPT, data_start,
5081                       p_msg->len, 0);
5082       status = BT_STATUS_SUCCESS;
5083     }
5084   } else {
5085     BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__,
5086                      status);
5087   }
5088   osi_free(p_msg);
5089   return (bt_status_t)status;
5090 }
5091 
5092 /***************************************************************************
5093  *
5094  * Function         send_register_abs_vol_rsp
5095  *
5096  * Description      Rsp for Notification of Absolute Volume
5097  *
5098  * Returns          void
5099  *
5100  **************************************************************************/
volume_change_notification_rsp(const RawAddress & bd_addr,btrc_notification_type_t rsp_type,uint8_t abs_vol,uint8_t label)5101 static bt_status_t volume_change_notification_rsp(
5102     const RawAddress& bd_addr, btrc_notification_type_t rsp_type,
5103     uint8_t abs_vol, uint8_t label) {
5104   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
5105   tAVRC_RESPONSE avrc_rsp;
5106   BT_HDR* p_msg = NULL;
5107   BTIF_TRACE_DEBUG("%s: rsp_type: %d abs_vol: %d", __func__, rsp_type, abs_vol);
5108 
5109   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
5110 
5111   CHECK_RC_CONNECTED(p_dev);
5112 
5113   avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
5114   avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
5115   avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
5116   avrc_rsp.reg_notif.param.volume = abs_vol;
5117   avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
5118 
5119   status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
5120   if (status == AVRC_STS_NO_ERROR) {
5121     BTIF_TRACE_DEBUG("%s: msgreq being sent out with label: %d", __func__,
5122                      label);
5123     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
5124     BTA_AvVendorRsp(p_dev->rc_handle, label,
5125                     (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM)
5126                         ? AVRC_RSP_INTERIM
5127                         : AVRC_RSP_CHANGED,
5128                     data_start, p_msg->len, 0);
5129     status = BT_STATUS_SUCCESS;
5130   } else {
5131     BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __func__,
5132                      status);
5133   }
5134   osi_free(p_msg);
5135 
5136   return (bt_status_t)status;
5137 }
5138 
5139 /***************************************************************************
5140  *
5141  * Function         send_groupnavigation_cmd
5142  *
5143  * Description      Send Pass-Through command
5144  *
5145  * Returns          void
5146  *
5147  **************************************************************************/
send_groupnavigation_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)5148 static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr,
5149                                             uint8_t key_code,
5150                                             uint8_t key_state) {
5151   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
5152   rc_transaction_t* p_transaction = NULL;
5153   BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __func__, key_code,
5154                    key_state);
5155   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
5156 
5157   CHECK_RC_CONNECTED(p_dev);
5158 
5159   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
5160     bt_status_t tran_status = get_transaction(&p_transaction);
5161     if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
5162       uint8_t buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
5163       uint8_t* start = buffer;
5164       UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
5165       *(start)++ = 0;
5166       UINT8_TO_BE_STREAM(start, key_code);
5167       BTA_AvRemoteVendorUniqueCmd(p_dev->rc_handle, p_transaction->lbl,
5168                                   (tBTA_AV_STATE)key_state, buffer,
5169                                   AVRC_PASS_THRU_GROUP_LEN);
5170       status = BT_STATUS_SUCCESS;
5171       BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
5172                        __func__);
5173     } else {
5174       status = BT_STATUS_FAIL;
5175       BTIF_TRACE_DEBUG("%s: error in fetching transaction", __func__);
5176     }
5177   } else {
5178     status = BT_STATUS_FAIL;
5179     BTIF_TRACE_DEBUG("%s: feature not supported", __func__);
5180   }
5181   return (bt_status_t)status;
5182 }
5183 
5184 /***************************************************************************
5185  *
5186  * Function         send_passthrough_cmd
5187  *
5188  * Description      Send Pass-Through command
5189  *
5190  * Returns          void
5191  *
5192  **************************************************************************/
send_passthrough_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)5193 static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr,
5194                                         uint8_t key_code, uint8_t key_state) {
5195   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
5196   btif_rc_device_cb_t* p_dev = NULL;
5197   BTIF_TRACE_ERROR("%s: calling btif_rc_get_device_by_bda", __func__);
5198   p_dev = btif_rc_get_device_by_bda(bd_addr);
5199 
5200   CHECK_RC_CONNECTED(p_dev);
5201 
5202   rc_transaction_t* p_transaction = NULL;
5203   BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __func__, key_code,
5204                    key_state);
5205   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
5206     bt_status_t tran_status = get_transaction(&p_transaction);
5207     if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) {
5208       BTA_AvRemoteCmd(p_dev->rc_handle, p_transaction->lbl,
5209                       (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
5210       status = BT_STATUS_SUCCESS;
5211       BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA",
5212                        __func__);
5213     } else {
5214       status = BT_STATUS_FAIL;
5215       BTIF_TRACE_DEBUG("%s: error in fetching transaction", __func__);
5216     }
5217   } else {
5218     status = BT_STATUS_FAIL;
5219     BTIF_TRACE_DEBUG("%s: feature not supported", __func__);
5220   }
5221   return (bt_status_t)status;
5222 }
5223 
5224 static const btrc_interface_t bt_rc_interface = {
5225     sizeof(bt_rc_interface),
5226     init,
5227     get_play_status_rsp,
5228     NULL, /* list_player_app_attr_rsp */
5229     NULL, /* list_player_app_value_rsp */
5230     NULL, /* get_player_app_value_rsp */
5231     NULL, /* get_player_app_attr_text_rsp */
5232     NULL, /* get_player_app_value_text_rsp */
5233     get_element_attr_rsp,
5234     NULL, /* set_player_app_value_rsp */
5235     register_notification_rsp,
5236     set_volume,
5237     set_addressed_player_rsp,
5238     set_browsed_player_rsp,
5239     get_folder_items_list_rsp,
5240     change_path_rsp,
5241     get_item_attr_rsp,
5242     play_item_rsp,
5243     get_total_num_of_items_rsp,
5244     search_rsp,
5245     add_to_now_playing_rsp,
5246     cleanup,
5247 };
5248 
5249 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
5250     sizeof(bt_rc_ctrl_interface),
5251     init_ctrl,
5252     send_passthrough_cmd,
5253     send_groupnavigation_cmd,
5254     change_player_app_setting,
5255     play_item_cmd,
5256     get_playback_state_cmd,
5257     get_now_playing_list_cmd,
5258     get_folder_list_cmd,
5259     get_player_list_cmd,
5260     change_folder_path_cmd,
5261     set_browsed_player_cmd,
5262     set_addressed_player_cmd,
5263     set_volume_rsp,
5264     volume_change_notification_rsp,
5265     cleanup_ctrl,
5266 };
5267 
5268 /*******************************************************************************
5269  *
5270  * Function         btif_rc_get_interface
5271  *
5272  * Description      Get the AVRCP Target callback interface
5273  *
5274  * Returns          btrc_interface_t
5275  *
5276  ******************************************************************************/
btif_rc_get_interface(void)5277 const btrc_interface_t* btif_rc_get_interface(void) {
5278   BTIF_TRACE_EVENT("%s: ", __func__);
5279   return &bt_rc_interface;
5280 }
5281 
5282 /*******************************************************************************
5283  *
5284  * Function         btif_rc_ctrl_get_interface
5285  *
5286  * Description      Get the AVRCP Controller callback interface
5287  *
5288  * Returns          btrc_ctrl_interface_t
5289  *
5290  ******************************************************************************/
btif_rc_ctrl_get_interface(void)5291 const btrc_ctrl_interface_t* btif_rc_ctrl_get_interface(void) {
5292   BTIF_TRACE_EVENT("%s: ", __func__);
5293   return &bt_rc_ctrl_interface;
5294 }
5295 
5296 /*******************************************************************************
5297  *      Function         initialize_transaction
5298  *
5299  *      Description    Initializes fields of the transaction structure
5300  *
5301  *      Returns          void
5302  ******************************************************************************/
initialize_transaction(int lbl)5303 static void initialize_transaction(int lbl) {
5304   std::unique_lock<std::recursive_mutex> lock(device.lbllock);
5305   if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
5306     if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
5307       clear_cmd_timeout(lbl);
5308     }
5309     device.transaction[lbl].lbl = lbl;
5310     device.transaction[lbl].in_use = false;
5311     device.transaction[lbl].handle = 0;
5312   }
5313 }
5314 
5315 /*******************************************************************************
5316  *      Function         lbl_init
5317  *
5318  *      Description    Initializes label structures and mutexes.
5319  *
5320  *      Returns         void
5321  ******************************************************************************/
lbl_init()5322 void lbl_init() {
5323   memset(&device.transaction, 0, sizeof(device.transaction));
5324   init_all_transactions();
5325 }
5326 
5327 /*******************************************************************************
5328  *
5329  * Function         init_all_transactions
5330  *
5331  * Description    Initializes all transactions
5332  *
5333  * Returns          void
5334  ******************************************************************************/
init_all_transactions()5335 void init_all_transactions() {
5336   uint8_t txn_indx = 0;
5337   for (txn_indx = 0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++) {
5338     initialize_transaction(txn_indx);
5339   }
5340 }
5341 
5342 /*******************************************************************************
5343  *
5344  * Function         get_transaction_by_lbl
5345  *
5346  * Description    Will return a transaction based on the label. If not inuse
5347  *                     will return an error.
5348  *
5349  * Returns          bt_status_t
5350  ******************************************************************************/
get_transaction_by_lbl(uint8_t lbl)5351 rc_transaction_t* get_transaction_by_lbl(uint8_t lbl) {
5352   rc_transaction_t* transaction = NULL;
5353   std::unique_lock<std::recursive_mutex> lock(device.lbllock);
5354 
5355   /* Determine if this is a valid label */
5356   if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
5357     if (!device.transaction[lbl].in_use) {
5358       transaction = NULL;
5359     } else {
5360       transaction = &(device.transaction[lbl]);
5361       BTIF_TRACE_DEBUG("%s: Got transaction.label: %d", __func__, lbl);
5362     }
5363   }
5364 
5365   return transaction;
5366 }
5367 
5368 /*******************************************************************************
5369  *
5370  * Function         get_transaction
5371  *
5372  * Description    Obtains the transaction details.
5373  *
5374  * Returns          bt_status_t
5375  ******************************************************************************/
5376 
get_transaction(rc_transaction_t ** ptransaction)5377 static bt_status_t get_transaction(rc_transaction_t** ptransaction) {
5378   std::unique_lock<std::recursive_mutex> lock(device.lbllock);
5379 
5380   // Check for unused transactions
5381   for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; i++) {
5382     if (!device.transaction[i].in_use) {
5383       BTIF_TRACE_DEBUG("%s: Got transaction.label: %d", __func__,
5384                        device.transaction[i].lbl);
5385       device.transaction[i].in_use = true;
5386       *ptransaction = &(device.transaction[i]);
5387       return BT_STATUS_SUCCESS;
5388     }
5389   }
5390   return BT_STATUS_NOMEM;
5391 }
5392 
5393 /*******************************************************************************
5394  *
5395  * Function         release_transaction
5396  *
5397  * Description    Will release a transaction for reuse
5398  *
5399  * Returns          bt_status_t
5400  ******************************************************************************/
release_transaction(uint8_t lbl)5401 void release_transaction(uint8_t lbl) {
5402   BTIF_TRACE_DEBUG("%s %d", __func__, lbl);
5403   rc_transaction_t* transaction = get_transaction_by_lbl(lbl);
5404 
5405   /* If the transaction is in use... */
5406   if (transaction != NULL) {
5407     BTIF_TRACE_DEBUG("%s: lbl: %d", __func__, lbl);
5408     initialize_transaction(lbl);
5409   }
5410 }
5411 
5412 /*******************************************************************************
5413  *      Function       sleep_ms
5414  *
5415  *      Description    Sleep the calling thread unconditionally for
5416  *                     |timeout_ms| milliseconds.
5417  *
5418  *      Returns        void
5419  ******************************************************************************/
sleep_ms(period_ms_t timeout_ms)5420 static void sleep_ms(period_ms_t timeout_ms) {
5421   struct timespec delay;
5422   delay.tv_sec = timeout_ms / 1000;
5423   delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000);
5424 
5425   OSI_NO_INTR(nanosleep(&delay, &delay));
5426 }
5427 
absolute_volume_disabled()5428 static bool absolute_volume_disabled() {
5429   char volume_disabled[PROPERTY_VALUE_MAX] = {0};
5430   osi_property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
5431   if (strncmp(volume_disabled, "true", 4) == 0) {
5432     BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__);
5433     return true;
5434   }
5435   return false;
5436 }
5437