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