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