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