• 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 <base/functional/bind.h>
30 #include <bluetooth/log.h>
31 #include <hardware/bluetooth.h>
32 #include <hardware/bt_rc.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <time.h>
36 
37 #include <cstdint>
38 #include <cstdio>
39 #include <mutex>
40 #include <sstream>
41 #include <string>
42 
43 #include "bta/include/bta_av_api.h"
44 #include "btif/avrcp/avrcp_service.h"
45 #include "btif_av.h"
46 #include "btif_common.h"
47 #include "btif_util.h"
48 #include "device/include/interop.h"
49 #include "osi/include/alarm.h"
50 #include "osi/include/allocator.h"
51 #include "osi/include/list.h"
52 #include "osi/include/osi.h"
53 #include "osi/include/properties.h"
54 #include "stack/include/avrc_api.h"
55 #include "stack/include/avrc_defs.h"
56 #include "stack/include/bt_hdr.h"
57 #include "stack/include/bt_types.h"
58 #include "types/raw_address.h"
59 
60 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
61 
62 /*****************************************************************************
63  *  Constants & Macros
64  *****************************************************************************/
65 
66 /* cod value for Headsets */
67 #define COD_AV_HEADSETS 0x0404
68 /* for AVRC 1.4 need to change this */
69 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
70 
71 #define IDX_GET_PLAY_STATUS_RSP 0
72 #define IDX_LIST_APP_ATTR_RSP 1
73 #define IDX_LIST_APP_VALUE_RSP 2
74 #define IDX_GET_CURR_APP_VAL_RSP 3
75 #define IDX_SET_APP_VAL_RSP 4
76 #define IDX_GET_APP_ATTR_TXT_RSP 5
77 #define IDX_GET_APP_VAL_TXT_RSP 6
78 #define IDX_GET_ELEMENT_ATTR_RSP 7
79 #define IDX_SET_ADDR_PLAYER_RSP 8
80 #define IDX_SET_BROWSED_PLAYER_RSP 9
81 #define IDX_GET_FOLDER_ITEMS_RSP 10
82 #define IDX_CHG_PATH_RSP 11
83 #define IDX_GET_ITEM_ATTR_RSP 12
84 #define IDX_PLAY_ITEM_RSP 13
85 #define IDX_GET_TOTAL_NUM_OF_ITEMS_RSP 14
86 #define IDX_SEARCH_RSP 15
87 #define IDX_ADD_TO_NOW_PLAYING_RSP 16
88 
89 /* Update MAX value whenever IDX will be changed */
90 #define MAX_CMD_QUEUE_LEN 17
91 
92 #define MAX_VOLUME 128
93 #define MAX_LABEL 16
94 #define MAX_TRANSACTIONS_PER_SESSION 16
95 #define PLAY_STATUS_PLAYING 1
96 #define BTIF_RC_NUM_CONN BT_RC_NUM_APP
97 
98 #define CHECK_RC_CONNECTED(p_dev)                    \
99   do {                                               \
100     if ((p_dev) == NULL || !(p_dev)->rc_connected) { \
101       log::warn("called when RC is not connected");  \
102       return BT_STATUS_NOT_READY;                    \
103     }                                                \
104   } while (0)
105 
106 #define CHECK_BR_CONNECTED(p_dev)                    \
107   do {                                               \
108     if ((p_dev) == NULL || !(p_dev)->br_connected) { \
109       log::warn("called when BR is not connected");  \
110       return BT_STATUS_NOT_READY;                    \
111     }                                                \
112   } while (0)
113 
114 using namespace bluetooth;
115 
116 /*****************************************************************************
117  *  Local type definitions
118  *****************************************************************************/
119 typedef struct {
120   uint8_t bNotify;
121   uint8_t label;
122 } btif_rc_reg_notifications_t;
123 
124 typedef struct {
125   uint8_t label;
126   uint8_t ctype;
127   bool is_rsp_pending;
128 } btif_rc_cmd_ctxt_t;
129 
130 /* 2 second timeout to get command response, then we free label */
131 #define BTIF_RC_TIMEOUT_MS (2 * 1000)
132 
133 typedef enum { eNOT_REGISTERED, eREGISTERED, eINTERIM } btif_rc_nfn_reg_status_t;
134 
135 typedef struct {
136   uint8_t event_id;
137   uint8_t label;
138   btif_rc_nfn_reg_status_t status;
139 } btif_rc_supported_event_t;
140 
141 #define BTIF_RC_STS_TIMEOUT 0xFE
142 
143 typedef struct {
144   bool query_started;
145   uint8_t num_attrs;
146   uint8_t num_ext_attrs;
147 
148   uint8_t attr_index;
149   uint8_t ext_attr_index;
150   uint8_t ext_val_index;
151   btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
152   btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
153 } btif_rc_player_app_settings_t;
154 
155 // The context associated with a passthru command
156 typedef struct {
157   uint8_t rc_id;
158   uint8_t key_state;
159   uint8_t custom_id;
160 } rc_passthru_context_t;
161 
162 // The context associated with a vendor command
163 typedef struct {
164   uint8_t pdu_id;
165   uint8_t event_id;
166 } rc_vendor_context_t;
167 
168 // The context associated with a browsing command
169 typedef struct {
170   uint8_t pdu_id;
171 } rc_browse_context_t;
172 
173 typedef union {
174   rc_vendor_context_t vendor;
175   rc_browse_context_t browse;
176   rc_passthru_context_t passthru;
177 } rc_command_context_t;
178 
179 // The context associated with any command transaction requiring a label.
180 // The opcode determines how to determine the data in the union. Context is
181 // used to track which requests have which labels
182 typedef struct {
183   RawAddress rc_addr;
184   uint8_t label;
185   uint8_t opcode;
186   rc_command_context_t command;
187 } rc_transaction_context_t;
188 typedef struct {
189   bool in_use;
190   uint8_t label;
191   rc_transaction_context_t context;
192   alarm_t* timer;
193 } rc_transaction_t;
194 
195 typedef struct {
196   std::recursive_mutex label_lock;
197   rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
198 } rc_transaction_set_t;
199 
200 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single
201  * struct */
202 typedef struct {
203   bool rc_connected;
204   bool br_connected;  // Browsing channel.
205   uint8_t rc_handle;
206   tBTA_AV_FEAT rc_features;
207   uint16_t rc_cover_art_psm;  // AVRCP-BIP psm
208   btrc_connection_state_t rc_state;
209   RawAddress rc_addr;
210   btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
211   btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
212   unsigned int rc_volume;
213   uint8_t rc_vol_label;
214   list_t* rc_supported_event_list;
215   btif_rc_player_app_settings_t rc_app_settings;
216   alarm_t* rc_play_status_timer;
217   bool rc_features_processed;
218   uint64_t rc_playing_uid;
219   bool rc_procedure_complete;
220   rc_transaction_set_t transaction_set;
221   tBTA_AV_FEAT peer_ct_features;
222   tBTA_AV_FEAT peer_tg_features;
223   uint8_t launch_cmd_pending; /* true: getcap/regvolume */
224 } btif_rc_device_cb_t;
225 
226 #define RC_PENDING_ACT_GET_CAP (1 << 0)
227 #define RC_PENDING_ACT_REG_VOL (1 << 1)
228 #define RC_PENDING_ACT_REPORT_CONN (1 << 2)
229 
230 typedef struct {
231   std::mutex lock;
232   btif_rc_device_cb_t rc_multi_cb[BTIF_RC_NUM_CONN];
233 } rc_cb_t;
234 
235 typedef struct {
236   uint8_t handle;
237 } btif_rc_handle_t;
238 
239 /* Response status code - Unknown Error - this is changed to "reserved" */
240 #define BTIF_STS_GEN_ERROR 0x06
241 
242 /* Utility table to map hal status codes to bta status codes for the response
243  * status */
244 static const uint8_t status_code_map[] = {
245         /* BTA_Status codes        HAL_Status codes */
246         AVRC_STS_BAD_CMD,         /* BTRC_STS_BAD_CMD */
247         AVRC_STS_BAD_PARAM,       /* BTRC_STS_BAD_PARAM */
248         AVRC_STS_NOT_FOUND,       /* BTRC_STS_NOT_FOUND */
249         AVRC_STS_INTERNAL_ERR,    /* BTRC_STS_INTERNAL_ERR */
250         AVRC_STS_NO_ERROR,        /* BTRC_STS_NO_ERROR */
251         AVRC_STS_UID_CHANGED,     /* BTRC_STS_UID_CHANGED */
252         BTIF_STS_GEN_ERROR,       /* BTRC_STS_RESERVED */
253         AVRC_STS_BAD_DIR,         /* BTRC_STS_INV_DIRN */
254         AVRC_STS_NOT_DIR,         /* BTRC_STS_INV_DIRECTORY */
255         AVRC_STS_NOT_EXIST,       /* BTRC_STS_INV_ITEM */
256         AVRC_STS_BAD_SCOPE,       /* BTRC_STS_INV_SCOPE */
257         AVRC_STS_BAD_RANGE,       /* BTRC_STS_INV_RANGE */
258         AVRC_STS_UID_IS_DIR,      /* BTRC_STS_DIRECTORY */
259         AVRC_STS_IN_USE,          /* BTRC_STS_MEDIA_IN_USE */
260         AVRC_STS_NOW_LIST_FULL,   /* BTRC_STS_PLAY_LIST_FULL */
261         AVRC_STS_SEARCH_NOT_SUP,  /* BTRC_STS_SRCH_NOT_SPRTD */
262         AVRC_STS_SEARCH_BUSY,     /* BTRC_STS_SRCH_IN_PROG */
263         AVRC_STS_BAD_PLAYER_ID,   /* BTRC_STS_INV_PLAYER */
264         AVRC_STS_PLAYER_N_BR,     /* BTRC_STS_PLAY_NOT_BROW */
265         AVRC_STS_PLAYER_N_ADDR,   /* BTRC_STS_PLAY_NOT_ADDR */
266         AVRC_STS_BAD_SEARCH_RES,  /* BTRC_STS_INV_RESULTS */
267         AVRC_STS_NO_AVAL_PLAYER,  /* BTRC_STS_NO_AVBL_PLAY */
268         AVRC_STS_ADDR_PLAYER_CHG, /* BTRC_STS_ADDR_PLAY_CHGD */
269 };
270 
271 static void initialize_device(btif_rc_device_cb_t* p_dev);
272 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, uint8_t status,
273                                  uint8_t opcode);
274 static void init_all_transactions(btif_rc_device_cb_t* p_dev);
275 static bt_status_t get_transaction(btif_rc_device_cb_t* p_dev, rc_transaction_context_t& context,
276                                    rc_transaction_t** ptransaction);
277 static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label, uint64_t timeout_ms);
278 static void btif_rc_transaction_timer_timeout(void* data);
279 static void release_transaction(btif_rc_device_cb_t* p_dev, uint8_t label);
280 static std::string dump_transaction(const rc_transaction_t* const transaction);
281 static rc_transaction_t* get_transaction_by_lbl(btif_rc_device_cb_t* p_dev, uint8_t label);
282 
283 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg);
284 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg);
285 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t label,
286                                            btif_rc_device_cb_t* p_dev);
287 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev);
288 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
289                                             btif_rc_device_cb_t* p_dev);
290 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_CAPS_RSP* p_rsp);
291 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_ATTR_RSP* p_rsp);
292 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_VALUES_RSP* p_rsp);
293 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
294                                         tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp);
295 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
296                                          tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
297 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg,
298                                              tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
299 static void cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t* p_app_settings);
300 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
301                                            tAVRC_GET_PLAY_STATUS_RSP* p_rsp);
302 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* p_rsp);
303 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, 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, tAVRC_RSP* p_rsp);
307 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev);
308 static bt_status_t get_player_app_setting_attr_text_cmd(uint8_t* attrs, uint8_t num_attrs,
309                                                         btif_rc_device_cb_t* p_dev);
310 static bt_status_t get_player_app_setting_value_text_cmd(uint8_t* vals, uint8_t num_vals,
311                                                          btif_rc_device_cb_t* p_dev);
312 static bt_status_t register_notification_cmd(uint8_t event_id, uint32_t event_value,
313                                              btif_rc_device_cb_t* p_dev);
314 static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
315                                               btif_rc_device_cb_t* p_dev);
316 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
317                                              btif_rc_device_cb_t* p_dev);
318 static bt_status_t get_item_attribute_cmd(uint64_t uid, int scope, uint8_t num_attribute,
319                                           const uint32_t* p_attr_ids, btif_rc_device_cb_t* p_dev);
320 static bt_status_t getcapabilities_cmd(uint8_t cap_id, btif_rc_device_cb_t* p_dev);
321 static bt_status_t list_player_app_setting_attrib_cmd(btif_rc_device_cb_t* p_dev);
322 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id, btif_rc_device_cb_t* p_dev);
323 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids,
324                                               btif_rc_device_cb_t* p_dev);
325 static void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, btrc_folder_items_t* btrc_item);
326 static void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
327                                         btrc_folder_items_t* btrc_item);
328 static void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
329                                         btrc_folder_items_t* btrc_item);
330 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, uint8_t scope,
331                                         uint32_t start_item, uint32_t end_item);
332 
333 /*****************************************************************************
334  *  Static variables
335  *****************************************************************************/
336 static rc_cb_t btif_rc_cb;
337 static btrc_ctrl_callbacks_t* bt_rc_ctrl_callbacks = NULL;
338 
339 // List of desired media attribute keys to request by default
340 static const uint32_t media_attr_list[] = {
341         AVRC_MEDIA_ATTR_ID_TITLE,        AVRC_MEDIA_ATTR_ID_ARTIST,
342         AVRC_MEDIA_ATTR_ID_ALBUM,        AVRC_MEDIA_ATTR_ID_TRACK_NUM,
343         AVRC_MEDIA_ATTR_ID_NUM_TRACKS,   AVRC_MEDIA_ATTR_ID_GENRE,
344         AVRC_MEDIA_ATTR_ID_PLAYING_TIME, AVRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE};
345 static const uint8_t media_attr_list_size = sizeof(media_attr_list) / sizeof(uint32_t);
346 
347 // List of desired media attribute keys to request if cover artwork is not a
348 // supported feature
349 static const uint32_t media_attr_list_no_cover_art[] = {
350         AVRC_MEDIA_ATTR_ID_TITLE,       AVRC_MEDIA_ATTR_ID_ARTIST,     AVRC_MEDIA_ATTR_ID_ALBUM,
351         AVRC_MEDIA_ATTR_ID_TRACK_NUM,   AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE,
352         AVRC_MEDIA_ATTR_ID_PLAYING_TIME};
353 static const uint8_t media_attr_list_no_cover_art_size =
354         sizeof(media_attr_list_no_cover_art) / sizeof(uint32_t);
355 
356 /*****************************************************************************
357  *  Static functions
358  *****************************************************************************/
359 
360 /*****************************************************************************
361  *  Externs
362  *****************************************************************************/
363 
btif_rc_get_addr_by_handle(uint8_t handle,RawAddress & rc_addr)364 void btif_rc_get_addr_by_handle(uint8_t handle, RawAddress& rc_addr) {
365   log::verbose("handle: 0x{:x}", handle);
366   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
367     if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
368         (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) {
369       log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}",
370                    btif_rc_cb.rc_multi_cb[idx].rc_handle);
371       rc_addr = btif_rc_cb.rc_multi_cb[idx].rc_addr;
372       return;
373     }
374   }
375   log::error("returning NULL");
376   rc_addr = RawAddress::kEmpty;
377   return;
378 }
379 
380 /*****************************************************************************
381  *  Functions
382  *****************************************************************************/
alloc_device()383 static btif_rc_device_cb_t* alloc_device() {
384   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
385     if (btif_rc_cb.rc_multi_cb[idx].rc_state == BTRC_CONNECTION_STATE_DISCONNECTED) {
386       return &btif_rc_cb.rc_multi_cb[idx];
387     }
388   }
389   return NULL;
390 }
391 
initialize_device(btif_rc_device_cb_t * p_dev)392 static void initialize_device(btif_rc_device_cb_t* p_dev) {
393   if (p_dev == nullptr) {
394     return;
395   }
396 
397   p_dev->rc_connected = false;
398   p_dev->br_connected = false;
399   p_dev->rc_handle = 0;
400   p_dev->rc_features = 0;
401   p_dev->rc_cover_art_psm = 0;
402   p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
403   p_dev->rc_addr = RawAddress::kEmpty;
404   for (int i = 0; i < MAX_CMD_QUEUE_LEN; ++i) {
405     p_dev->rc_pdu_info[i].ctype = 0;
406     p_dev->rc_pdu_info[i].label = 0;
407     p_dev->rc_pdu_info[i].is_rsp_pending = false;
408   }
409   if (p_dev->rc_supported_event_list != nullptr) {
410     list_clear(p_dev->rc_supported_event_list);
411   }
412   p_dev->rc_supported_event_list = nullptr;
413   p_dev->rc_volume = MAX_VOLUME;
414   p_dev->rc_vol_label = MAX_LABEL;
415   memset(&p_dev->rc_app_settings, 0, sizeof(btif_rc_player_app_settings_t));
416   p_dev->rc_play_status_timer = nullptr;
417   p_dev->rc_features_processed = false;
418   p_dev->rc_playing_uid = 0;
419   p_dev->rc_procedure_complete = false;
420   p_dev->peer_ct_features = 0;
421   p_dev->peer_tg_features = 0;
422   p_dev->launch_cmd_pending = 0;
423 
424   // Reset the transaction set for this device. If this initialize_device() call
425   // is made due to a disconnect event, this cancels any pending timers too.
426   init_all_transactions(p_dev);
427 }
428 
get_connected_device(int index)429 static btif_rc_device_cb_t* get_connected_device(int index) {
430   log::verbose("index: {}", index);
431   if (index >= BTIF_RC_NUM_CONN) {
432     log::error("can't support more than {} connections", BTIF_RC_NUM_CONN);
433     return NULL;
434   }
435   if (btif_rc_cb.rc_multi_cb[index].rc_state != BTRC_CONNECTION_STATE_CONNECTED) {
436     log::error("returning NULL");
437     return NULL;
438   }
439   return &btif_rc_cb.rc_multi_cb[index];
440 }
441 
btif_rc_get_device_by_bda(const RawAddress & bd_addr)442 static btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) {
443   log::verbose("bd_addr: {}", bd_addr);
444 
445   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
446     if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
447         btif_rc_cb.rc_multi_cb[idx].rc_addr == bd_addr) {
448       return &btif_rc_cb.rc_multi_cb[idx];
449     }
450   }
451   log::error("device not found, returning NULL!");
452   return NULL;
453 }
454 
btif_rc_get_device_by_handle(uint8_t handle)455 static btif_rc_device_cb_t* btif_rc_get_device_by_handle(uint8_t handle) {
456   log::verbose("handle: 0x{:x}", handle);
457   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
458     if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
459         (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) {
460       log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}",
461                    btif_rc_cb.rc_multi_cb[idx].rc_handle);
462       return &btif_rc_cb.rc_multi_cb[idx];
463     }
464   }
465   log::error("returning NULL");
466   return NULL;
467 }
468 
get_requested_attributes_list(btif_rc_device_cb_t * p_dev)469 static const uint32_t* get_requested_attributes_list(btif_rc_device_cb_t* p_dev) {
470   return p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK ? media_attr_list
471                                                         : media_attr_list_no_cover_art;
472 }
473 
get_requested_attributes_list_size(btif_rc_device_cb_t * p_dev)474 static uint8_t get_requested_attributes_list_size(btif_rc_device_cb_t* p_dev) {
475   return p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK ? media_attr_list_size
476                                                         : media_attr_list_no_cover_art_size;
477 }
478 
handle_rc_ctrl_features_all(btif_rc_device_cb_t * p_dev)479 static void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) {
480   if (!(p_dev->peer_tg_features & BTA_AV_FEAT_RCTG) &&
481       (!(p_dev->peer_tg_features & BTA_AV_FEAT_RCCT) ||
482        !(p_dev->peer_tg_features & BTA_AV_FEAT_ADV_CTRL))) {
483     return;
484   }
485 
486   int rc_features = 0;
487 
488   log::verbose(
489           "peer_tg_features: 0x{:x}, rc_features_processed={}, connected={}, "
490           "peer_is_src:{}",
491           p_dev->peer_tg_features, p_dev->rc_features_processed,
492           btif_av_is_connected_addr(p_dev->rc_addr, A2dpType::kSink),
493           btif_av_peer_is_source(p_dev->rc_addr));
494 
495   if ((p_dev->peer_tg_features & BTA_AV_FEAT_ADV_CTRL) &&
496       (p_dev->peer_tg_features & BTA_AV_FEAT_RCCT)) {
497     rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
498   }
499 
500   if ((p_dev->peer_tg_features & BTA_AV_FEAT_METADATA) &&
501       (p_dev->peer_tg_features & BTA_AV_FEAT_VENDOR) && (p_dev->rc_features_processed != true)) {
502     rc_features |= BTRC_FEAT_METADATA;
503 
504     /* Mark rc features processed to avoid repeating
505      * the AVRCP procedure every time on receiving this
506      * update.
507      */
508     p_dev->rc_features_processed = true;
509   }
510 
511   if (btif_av_is_connected_addr(p_dev->rc_addr, A2dpType::kSink)) {
512     if (btif_av_peer_is_source(p_dev->rc_addr)) {
513       p_dev->rc_features = p_dev->peer_tg_features;
514       if ((p_dev->peer_tg_features & BTA_AV_FEAT_METADATA) &&
515           (p_dev->peer_tg_features & BTA_AV_FEAT_VENDOR)) {
516         getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
517       }
518     }
519   } else {
520     log::verbose("{} is not connected, pending", p_dev->rc_addr);
521     p_dev->launch_cmd_pending |= (RC_PENDING_ACT_GET_CAP | RC_PENDING_ACT_REG_VOL);
522   }
523 
524   /* Add browsing feature capability */
525   if (p_dev->peer_tg_features & BTA_AV_FEAT_BROWSE) {
526     rc_features |= BTRC_FEAT_BROWSE;
527   }
528 
529   /* Add cover art feature capability */
530   if (p_dev->peer_tg_features & BTA_AV_FEAT_COVER_ARTWORK) {
531     rc_features |= BTRC_FEAT_COVER_ARTWORK;
532   }
533 
534   if (bt_rc_ctrl_callbacks != NULL) {
535     log::verbose("Update rc features to CTRL: {}", rc_features);
536     do_in_jni_thread(
537             base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features));
538   }
539 }
540 
handle_rc_ctrl_features(btif_rc_device_cb_t * p_dev)541 static void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) {
542   if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
543     handle_rc_ctrl_features_all(p_dev);
544     return;
545   }
546 
547   if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG) &&
548       (!(p_dev->rc_features & BTA_AV_FEAT_RCCT) || !(p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL))) {
549     return;
550   }
551 
552   int rc_features = 0;
553 
554   if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) && (p_dev->rc_features & BTA_AV_FEAT_RCCT)) {
555     rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
556   }
557 
558   if (p_dev->rc_features & BTA_AV_FEAT_METADATA) {
559     rc_features |= BTRC_FEAT_METADATA;
560   }
561 
562   if ((p_dev->rc_features & BTA_AV_FEAT_VENDOR) && (p_dev->rc_features_processed != true)) {
563     /* Mark rc features processed to avoid repeating
564      * the AVRCP procedure every time on receiving this
565      * update.
566      */
567     p_dev->rc_features_processed = true;
568     if (btif_av_is_sink_enabled()) {
569       getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
570     }
571   }
572 
573   /* Add browsing feature capability */
574   if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) {
575     rc_features |= BTRC_FEAT_BROWSE;
576   }
577 
578   /* Add cover art feature capability */
579   if (p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK) {
580     rc_features |= BTRC_FEAT_COVER_ARTWORK;
581   }
582 
583   log::verbose("Update rc features to CTRL: {}", rc_features);
584   do_in_jni_thread(
585           base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features));
586 }
btif_rc_check_pending_cmd(const RawAddress & peer_address)587 void btif_rc_check_pending_cmd(const RawAddress& peer_address) {
588   btif_rc_device_cb_t* p_dev = NULL;
589   p_dev = btif_rc_get_device_by_bda(peer_address);
590   if (p_dev == NULL) {
591     log::error("p_dev NULL");
592     return;
593   }
594 
595   log::verbose(
596           "launch_cmd_pending={}, rc_connected={}, peer_ct_features=0x{:x}, "
597           "peer_tg_features=0x{:x}",
598           p_dev->launch_cmd_pending, p_dev->rc_connected, p_dev->peer_ct_features,
599           p_dev->peer_tg_features);
600   if (p_dev->launch_cmd_pending && p_dev->rc_connected) {
601     if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REG_VOL) &&
602         btif_av_peer_is_sink(p_dev->rc_addr)) {
603       if (bluetooth::avrcp::AvrcpService::Get() != nullptr) {
604         bluetooth::avrcp::AvrcpService::Get()->RegisterVolChanged(peer_address);
605       }
606     }
607     if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_GET_CAP) &&
608         btif_av_peer_is_source(p_dev->rc_addr)) {
609       p_dev->rc_features = p_dev->peer_tg_features;
610       getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
611     }
612     if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REPORT_CONN) &&
613         btif_av_peer_is_source(p_dev->rc_addr)) {
614       if (bt_rc_ctrl_callbacks != NULL) {
615         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, false,
616                                         p_dev->rc_addr));
617       }
618     }
619   }
620   p_dev->launch_cmd_pending = 0;
621 }
622 
handle_rc_ctrl_psm(btif_rc_device_cb_t * p_dev)623 static void handle_rc_ctrl_psm(btif_rc_device_cb_t* p_dev) {
624   uint16_t cover_art_psm = p_dev->rc_cover_art_psm;
625   log::verbose("Update rc cover art psm to CTRL: {}", cover_art_psm);
626   if (bt_rc_ctrl_callbacks != NULL) {
627     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_cover_art_psm_cb, p_dev->rc_addr,
628                                     cover_art_psm));
629   }
630 }
631 
632 /***************************************************************************
633  *  Function       handle_rc_browse_connect
634  *
635  *  - Argument:    tBTA_AV_RC_OPEN  browse RC open data structure
636  *
637  *  - Description: browse RC connection event handler
638  *
639  ***************************************************************************/
handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN * p_rc_br_open)640 static void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) {
641   log::verbose("rc_handle {} status {}", p_rc_br_open->rc_handle, p_rc_br_open->status);
642   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(p_rc_br_open->rc_handle);
643 
644   if (!p_dev) {
645     log::error("p_dev is null");
646     return;
647   }
648 
649   /* check that we are already connected to this address since being connected
650    * to a browse when not connected to the control channel over AVRCP is
651    * probably not preferred anyways. */
652   if (p_rc_br_open->status == BTA_AV_SUCCESS) {
653     p_dev->br_connected = true;
654     if (btif_av_src_sink_coexist_enabled()) {
655       if (btif_av_peer_is_connected_source(p_dev->rc_addr)) {
656         if (bt_rc_ctrl_callbacks != NULL) {
657           do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, true,
658                                           p_dev->rc_addr));
659         }
660       } else {
661         p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN;
662         log::verbose("pending rc browse connection event");
663       }
664     } else {
665       if (bt_rc_ctrl_callbacks != NULL) {
666         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, true,
667                                         p_dev->rc_addr));
668       } else {
669         log::warn("bt_rc_ctrl_callbacks is null.");
670       }
671     }
672   }
673 }
674 
675 /***************************************************************************
676  *  Function       handle_rc_connect
677  *
678  *  - Argument:    tBTA_AV_RC_OPEN  RC open data structure
679  *
680  *  - Description: RC connection event handler
681  *
682  ***************************************************************************/
handle_rc_connect(tBTA_AV_RC_OPEN * p_rc_open)683 static void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) {
684   log::verbose("rc_handle: {}", p_rc_open->rc_handle);
685 
686   btif_rc_device_cb_t* p_dev = alloc_device();
687   if (p_dev == NULL) {
688     log::error("p_dev is NULL");
689     return;
690   }
691 
692   if (!(p_rc_open->status == BTA_AV_SUCCESS)) {
693     log::error("Connect failed with error code: {}", p_rc_open->status);
694     p_dev->rc_connected = false;
695     BTA_AvCloseRc(p_rc_open->rc_handle);
696     p_dev->rc_handle = 0;
697     p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
698     p_dev->rc_features = 0;
699     p_dev->peer_ct_features = 0;
700     p_dev->peer_tg_features = 0;
701     p_dev->launch_cmd_pending = 0;
702     p_dev->rc_vol_label = MAX_LABEL;
703     p_dev->rc_volume = MAX_VOLUME;
704     p_dev->rc_addr = RawAddress::kEmpty;
705     return;
706   }
707 
708   // check if already some RC is connected
709   if (p_dev->rc_connected) {
710     log::error("Got RC OPEN in connected state, Connected RC: {} and Current RC: {}",
711                p_dev->rc_handle, p_rc_open->rc_handle);
712     if (p_dev->rc_handle != p_rc_open->rc_handle && p_dev->rc_addr != p_rc_open->peer_addr) {
713       log::verbose("Got RC connected for some other handle");
714       BTA_AvCloseRc(p_rc_open->rc_handle);
715       return;
716     }
717   }
718   p_dev->rc_addr = p_rc_open->peer_addr;
719   p_dev->rc_features = p_rc_open->peer_features;
720   p_dev->peer_ct_features = p_rc_open->peer_ct_features;
721   p_dev->peer_tg_features = p_rc_open->peer_tg_features;
722   p_dev->rc_cover_art_psm = p_rc_open->cover_art_psm;
723   p_dev->rc_vol_label = MAX_LABEL;
724   p_dev->rc_volume = MAX_VOLUME;
725 
726   log::verbose(
727           "handle_rc_connect in features={:#x}, out features={:#x}, "
728           "ct_feature={:#x}, tg_feature={:#x}, cover art psm={:#x}",
729           p_rc_open->peer_features, p_dev->rc_features, p_dev->peer_ct_features,
730           p_dev->peer_tg_features, p_dev->rc_cover_art_psm);
731 
732   p_dev->rc_connected = true;
733   p_dev->rc_handle = p_rc_open->rc_handle;
734   p_dev->rc_state = BTRC_CONNECTION_STATE_CONNECTED;
735 
736   p_dev->rc_playing_uid = RC_INVALID_TRACK_ID;
737 
738   if (btif_av_src_sink_coexist_enabled() && !btif_av_peer_is_connected_source(p_dev->rc_addr)) {
739     p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN;
740     log::verbose("pending rc connection event");
741     return;
742   }
743   if (bt_rc_ctrl_callbacks != NULL) {
744     do_in_jni_thread(
745             base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, false, p_dev->rc_addr));
746     /* report connection state if remote device is AVRCP target */
747     handle_rc_ctrl_features(p_dev);
748 
749     /* report psm if remote device is AVRCP target */
750     handle_rc_ctrl_psm(p_dev);
751   }
752 }
753 
754 /***************************************************************************
755  *  Function       handle_rc_disconnect
756  *
757  *  - Argument:    tBTA_AV_RC_CLOSE     RC close data structure
758  *
759  *  - Description: RC disconnection event handler
760  *
761  ***************************************************************************/
handle_rc_disconnect(tBTA_AV_RC_CLOSE * p_rc_close)762 static void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) {
763   btif_rc_device_cb_t* p_dev = NULL;
764   log::verbose("rc_handle: {}", p_rc_close->rc_handle);
765 
766   p_dev = btif_rc_get_device_by_handle(p_rc_close->rc_handle);
767   if (p_dev == NULL) {
768     log::error("Got disconnect from invalid rc handle");
769     return;
770   }
771 
772   if (p_rc_close->rc_handle != p_dev->rc_handle && p_dev->rc_addr != p_rc_close->peer_addr) {
773     log::error("Got disconnect of unknown device");
774     return;
775   }
776 
777   /* Report connection state if device is AVRCP target */
778   if (bt_rc_ctrl_callbacks != NULL) {
779     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, false, false,
780                                     p_dev->rc_addr));
781   }
782 
783   // We'll re-initialize the device state back to what it looked like before
784   // the connection. This will free ongoing transaction labels and clear any
785   // running label timers
786   initialize_device(p_dev);
787 }
788 
789 /***************************************************************************
790  *  Function       handle_rc_passthrough_rsp
791  *
792  *  - Argument:    tBTA_AV_REMOTE_RSP passthrough command response
793  *
794  *  - Description: Remote control passthrough response handler
795  *
796  ***************************************************************************/
handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)797 static void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
798   btif_rc_device_cb_t* p_dev = NULL;
799 
800   p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
801   if (p_dev == NULL) {
802     log::error("passthrough response for Invalid rc handle");
803     return;
804   }
805 
806   if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
807     log::error("DUT does not support AVRCP controller role");
808     return;
809   }
810 
811   const char* status = (p_remote_rsp->key_state == 1) ? "released" : "pressed";
812   log::verbose("rc_id: {} state: {}", p_remote_rsp->rc_id, status);
813 
814   release_transaction(p_dev, p_remote_rsp->label);
815   if (bt_rc_ctrl_callbacks != NULL) {
816     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr,
817                                     p_remote_rsp->rc_id, p_remote_rsp->key_state));
818   }
819 }
820 
821 /***************************************************************************
822  *  Function       handle_rc_vendorunique_rsp
823  *
824  *  - Argument:    tBTA_AV_REMOTE_RSP  command response
825  *
826  *  - Description: Remote control vendor unique response handler
827  *
828  ***************************************************************************/
handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)829 static void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
830   btif_rc_device_cb_t* p_dev = NULL;
831   const char* status;
832   uint8_t vendor_id = 0;
833 
834   p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
835   if (p_dev == NULL) {
836     log::error("Got vendorunique rsp from invalid rc handle");
837     return;
838   }
839 
840   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
841     int key_state;
842     if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) {
843       status = "released";
844       key_state = 1;
845     } else {
846       status = "pressed";
847       key_state = 0;
848     }
849 
850     if (p_remote_rsp->len > 0 && p_remote_rsp->p_data != NULL) {
851       if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN) {
852         vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN - 1];
853       }
854       osi_free_and_reset((void**)&p_remote_rsp->p_data);
855     }
856     log::verbose("vendor_id: {} status: {}", vendor_id, status);
857 
858     release_transaction(p_dev, p_remote_rsp->label);
859     do_in_jni_thread(
860             base::BindOnce(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, vendor_id, key_state));
861   } else {
862     log::error("Remote does not support AVRCP TG role");
863   }
864 }
865 
866 /***************************************************************************
867  **
868  ** Function       btif_rc_handler
869  **
870  ** Description    RC event handler
871  **
872  ***************************************************************************/
btif_rc_handler(tBTA_AV_EVT event,tBTA_AV * p_data)873 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) {
874   log::verbose("event: {}", dump_rc_event(event));
875   btif_rc_device_cb_t* p_dev = NULL;
876   switch (event) {
877     case BTA_AV_RC_OPEN_EVT: {
878       log::verbose("Peer_features: 0x{:x} Cover Art PSM: 0x{:x}", p_data->rc_open.peer_features,
879                    p_data->rc_open.cover_art_psm);
880       handle_rc_connect(&(p_data->rc_open));
881     } break;
882 
883     case BTA_AV_RC_BROWSE_OPEN_EVT: {
884       /* tell the UL that we have connection to browse channel and that
885        * browse commands can be directed accordingly. */
886       handle_rc_browse_connect(&p_data->rc_browse_open);
887     } break;
888 
889     case BTA_AV_RC_CLOSE_EVT: {
890       handle_rc_disconnect(&(p_data->rc_close));
891     } break;
892 
893     case BTA_AV_RC_BROWSE_CLOSE_EVT: {
894       log::verbose("BTA_AV_RC_BROWSE_CLOSE_EVT");
895     } break;
896 
897     case BTA_AV_REMOTE_CMD_EVT: {
898       log::error("AVRCP TG role not up, drop passthrough commands");
899     } break;
900 
901     case BTA_AV_REMOTE_RSP_EVT: {
902       log::verbose("RSP: rc_id: 0x{:x} key_state: {}", p_data->remote_rsp.rc_id,
903                    p_data->remote_rsp.key_state);
904 
905       if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) {
906         handle_rc_vendorunique_rsp(&p_data->remote_rsp);
907       } else {
908         handle_rc_passthrough_rsp(&p_data->remote_rsp);
909       }
910     } break;
911 
912     case BTA_AV_RC_FEAT_EVT: {
913       log::verbose("Peer_features: {:x}", p_data->rc_feat.peer_features);
914       p_dev = btif_rc_get_device_by_handle(p_data->rc_feat.rc_handle);
915       if (p_dev == NULL) {
916         log::error("RC Feature event for Invalid rc handle");
917         break;
918       }
919       log::verbose("peer_ct_features:0x{:x}, peer_tg_features=0x{:x}",
920                    p_data->rc_feat.peer_ct_features, p_data->rc_feat.peer_tg_features);
921       if (btif_av_src_sink_coexist_enabled() &&
922           (p_dev->peer_ct_features == p_data->rc_feat.peer_ct_features) &&
923           (p_dev->peer_tg_features == p_data->rc_feat.peer_tg_features)) {
924         log::error("do SDP twice, no need callback rc_feature to framework again");
925         break;
926       }
927 
928       p_dev->peer_ct_features = p_data->rc_feat.peer_ct_features;
929       p_dev->peer_tg_features = p_data->rc_feat.peer_tg_features;
930       p_dev->rc_features = p_data->rc_feat.peer_features;
931 
932       if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) {
933         handle_rc_ctrl_features(p_dev);
934       }
935     } break;
936 
937     case BTA_AV_RC_PSM_EVT: {
938       log::verbose("Peer cover art PSM: {:x}", p_data->rc_cover_art_psm.cover_art_psm);
939       p_dev = btif_rc_get_device_by_handle(p_data->rc_cover_art_psm.rc_handle);
940       if (p_dev == NULL) {
941         log::error("RC PSM event for Invalid rc handle");
942         break;
943       }
944 
945       p_dev->rc_cover_art_psm = p_data->rc_cover_art_psm.cover_art_psm;
946       if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) {
947         handle_rc_ctrl_psm(p_dev);
948       }
949     } break;
950 
951     case BTA_AV_META_MSG_EVT: {
952       if (bt_rc_ctrl_callbacks != NULL) {
953         /* This is case of Sink + CT + TG(for abs vol)) */
954         log::verbose("BTA_AV_META_MSG_EVT code:{} label:{} opcode {} ctype {}",
955                      p_data->meta_msg.code, p_data->meta_msg.label,
956                      p_data->meta_msg.p_msg->hdr.opcode, p_data->meta_msg.p_msg->hdr.ctype);
957         log::verbose("company_id:0x{:x} len:{} handle:{}", p_data->meta_msg.company_id,
958                      p_data->meta_msg.len, p_data->meta_msg.rc_handle);
959         switch (p_data->meta_msg.p_msg->hdr.opcode) {
960           case AVRC_OP_VENDOR:
961             if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL) &&
962                 (p_data->meta_msg.code <= AVRC_RSP_INTERIM)) {
963               /* Its a response */
964               handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
965             } else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ) {
966               /* Its a command  */
967               handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
968             }
969             break;
970 
971           case AVRC_OP_BROWSE:
972             if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_CMD) {
973               handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
974             } else if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_RSP) {
975               handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
976             }
977             break;
978         }
979       } else {
980         log::error("Neither CTRL, nor TG is up, drop meta commands");
981       }
982     } break;
983 
984     default:
985       log::verbose("Unhandled RC event : 0x{:x}", event);
986   }
987 }
988 
btif_rc_is_connected_peer(const RawAddress & peer_addr)989 bool btif_rc_is_connected_peer(const RawAddress& peer_addr) {
990   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
991     btif_rc_device_cb_t* p_dev = get_connected_device(idx);
992     if (p_dev != NULL && p_dev->rc_connected && peer_addr == p_dev->rc_addr) {
993       return true;
994     }
995   }
996   return false;
997 }
998 
999 /***************************************************************************
1000  **
1001  ** Function       btif_rc_get_connected_peer_handle
1002  **
1003  ** Description    Fetches the connected headset's handle if any
1004  **
1005  ***************************************************************************/
btif_rc_get_connected_peer_handle(const RawAddress & peer_addr)1006 uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) {
1007   btif_rc_device_cb_t* p_dev = NULL;
1008   p_dev = btif_rc_get_device_by_bda(peer_addr);
1009 
1010   if (p_dev == NULL) {
1011     log::error("p_dev NULL");
1012     return BTRC_HANDLE_NONE;
1013   }
1014   return p_dev->rc_handle;
1015 }
1016 
1017 /* Generic reject response */
send_reject_response(uint8_t rc_handle,uint8_t label,uint8_t pdu,uint8_t status,uint8_t opcode)1018 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, uint8_t status,
1019                                  uint8_t opcode) {
1020   uint8_t ctype = AVRC_RSP_REJ;
1021   tAVRC_RESPONSE avrc_rsp;
1022   BT_HDR* p_msg = NULL;
1023   memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1024 
1025   avrc_rsp.rsp.opcode = opcode;
1026   avrc_rsp.rsp.pdu = pdu;
1027   avrc_rsp.rsp.status = status;
1028 
1029   status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg);
1030 
1031   if (status != AVRC_STS_NO_ERROR) {
1032     log::error("status not AVRC_STS_NO_ERROR");
1033     return;
1034   }
1035 
1036   log::verbose("Sending error notification to handle: {}. pdu: {},status: 0x{:02x}", rc_handle,
1037                dump_rc_pdu(pdu), status);
1038   BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1039 }
1040 
1041 /*******************************************************************************
1042  *
1043  * Function         btif_rc_ctrl_upstreams_rsp_cmd
1044  *
1045  * Description      Executes AVRC UPSTREAMS response events in btif context.
1046  *
1047  * Returns          void
1048  *
1049  ******************************************************************************/
btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event,tAVRC_COMMAND * pavrc_cmd,uint8_t label,btif_rc_device_cb_t * p_dev)1050 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t label,
1051                                            btif_rc_device_cb_t* p_dev) {
1052   log::verbose("pdu: {}: handle: 0x{:x}", dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle);
1053   switch (event) {
1054     case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1055       do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr,
1056                                       pavrc_cmd->volume.volume, label));
1057       break;
1058     case AVRC_PDU_REGISTER_NOTIFICATION:
1059       if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) {
1060         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->registernotification_absvol_cb,
1061                                         p_dev->rc_addr, label));
1062       }
1063       break;
1064   }
1065 }
1066 
1067 /*******************************************************************************
1068  *  AVRCP API Functions
1069  ******************************************************************************/
1070 
1071 /*******************************************************************************
1072  *
1073  * Function         init_ctrl
1074  *
1075  * Description      Initializes the AVRC interface
1076  *
1077  * Returns          bt_status_t
1078  *
1079  ******************************************************************************/
init_ctrl(btrc_ctrl_callbacks_t * callbacks)1080 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) {
1081   log::verbose("");
1082   bt_status_t result = BT_STATUS_SUCCESS;
1083 
1084   if (bt_rc_ctrl_callbacks) {
1085     return BT_STATUS_DONE;
1086   }
1087 
1088   bt_rc_ctrl_callbacks = callbacks;
1089 
1090   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1091     initialize_device(&btif_rc_cb.rc_multi_cb[idx]);
1092   }
1093 
1094   return result;
1095 }
1096 
rc_ctrl_procedure_complete(btif_rc_device_cb_t * p_dev)1097 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev) {
1098   if (p_dev == NULL) {
1099     log::error("p_dev NULL");
1100     return;
1101   }
1102 
1103   if (p_dev->rc_procedure_complete) {
1104     return;
1105   }
1106   p_dev->rc_procedure_complete = true;
1107   const uint32_t* attr_list = get_requested_attributes_list(p_dev);
1108   const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
1109   get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1110 }
1111 
1112 /***************************************************************************
1113  *
1114  * Function         iterate_supported_event_list_for_interim_rsp
1115  *
1116  * Description      iterator callback function to match the event and handle
1117  *                  timer cleanup
1118  * Returns          true to continue iterating, false to stop
1119  *
1120  **************************************************************************/
iterate_supported_event_list_for_interim_rsp(void * data,void * cb_data)1121 static bool iterate_supported_event_list_for_interim_rsp(void* data, void* cb_data) {
1122   uint8_t* p_event_id;
1123   btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data;
1124 
1125   p_event_id = (uint8_t*)cb_data;
1126 
1127   if (p_event->event_id == *p_event_id) {
1128     p_event->status = eINTERIM;
1129     return false;
1130   }
1131   return true;
1132 }
1133 
1134 /***************************************************************************
1135  *
1136  * Function         rc_notification_interim_timeout
1137  *
1138  * Description      Interim response timeout handler.
1139  *                  Runs the iterator to check and clear the timed out event.
1140  *                  Proceeds to register for the unregistered events.
1141  * Returns          None
1142  *
1143  **************************************************************************/
rc_notification_interim_timeout(btif_rc_device_cb_t * p_dev,uint8_t event_id)1144 static void rc_notification_interim_timeout(btif_rc_device_cb_t* p_dev, uint8_t event_id) {
1145   /* Device disconnections clear the event list but can't free the timer */
1146   if (p_dev == NULL || p_dev->rc_supported_event_list == NULL) {
1147     log::warn("timeout for null device or event list");
1148     return;
1149   }
1150 
1151   // Remove the timed out event from the supported events list
1152   list_node_t* node = list_begin(p_dev->rc_supported_event_list);
1153   while (node != NULL) {
1154     btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)list_node(node);
1155     if (p_event != nullptr && p_event->event_id == event_id) {
1156       list_remove(p_dev->rc_supported_event_list, p_event);
1157       break;
1158     }
1159     node = list_next(node);
1160   }
1161 
1162   /* Timeout happened for interim response for the registered event,
1163    * check if there are any pending for registration
1164    */
1165   node = list_begin(p_dev->rc_supported_event_list);
1166   while (node != NULL) {
1167     btif_rc_supported_event_t* p_event;
1168 
1169     p_event = (btif_rc_supported_event_t*)list_node(node);
1170     if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
1171       register_for_event_notification(p_event, p_dev);
1172       break;
1173     }
1174     node = list_next(node);
1175   }
1176   /* Todo. Need to initiate application settings query if this
1177    * is the last event registration.
1178    */
1179 }
1180 
1181 /***************************************************************************
1182  *
1183  * Function         register_for_event_notification
1184  *
1185  * Description      Helper function registering notification events
1186  *                  sets an interim response timeout to handle if the remote
1187  *                  does not respond.
1188  * Returns          None
1189  *
1190  **************************************************************************/
register_for_event_notification(btif_rc_supported_event_t * p_event,btif_rc_device_cb_t * p_dev)1191 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
1192                                             btif_rc_device_cb_t* p_dev) {
1193   // interval is only valid for AVRC_EVT_PLAY_POS_CHANGED
1194   uint32_t interval_in_seconds = 0;
1195   if (p_event->event_id == AVRC_EVT_PLAY_POS_CHANGED) {
1196     interval_in_seconds = 2;
1197   }
1198   bt_status_t status = register_notification_cmd(p_event->event_id, interval_in_seconds, p_dev);
1199   if (status != BT_STATUS_SUCCESS) {
1200     log::error("failed, status={}", status);
1201     return;
1202   }
1203 
1204   p_event->status = eREGISTERED;
1205 }
1206 
1207 /***************************************************************************
1208  *
1209  * Function         build_and_send_vendor_cmd
1210  *
1211  * Description      Send a command to a device on the browsing channel
1212  *
1213  * Parameters       avrc_cmd: The command you're sending
1214  *                  p_dev: Device control block
1215  *
1216  * Returns          BT_STATUS_SUCCESS if command is issued successfully
1217  *                  otherwise BT_STATUS_FAIL
1218  *
1219  **************************************************************************/
build_and_send_vendor_cmd(tAVRC_COMMAND * avrc_cmd,tBTA_AV_CODE cmd_code,btif_rc_device_cb_t * p_dev)1220 static bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd, tBTA_AV_CODE cmd_code,
1221                                              btif_rc_device_cb_t* p_dev) {
1222   rc_transaction_t* p_transaction = NULL;
1223   rc_transaction_context_t context = {.rc_addr = p_dev->rc_addr,
1224                                       .label = MAX_LABEL,
1225                                       .opcode = AVRC_OP_VENDOR,
1226                                       .command = {.vendor = {avrc_cmd->pdu, AVRC_EVT_INVALID}}};
1227 
1228   // Set the event ID in the context if this is a notification registration
1229   if (avrc_cmd->pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
1230     context.command.vendor.event_id = avrc_cmd->reg_notif.event_id;
1231   }
1232 
1233   bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
1234   if (BT_STATUS_SUCCESS != tran_status || p_transaction == NULL) {
1235     log::error("failed to get label, pdu_id={}, status=0x{:02x}", dump_rc_pdu(avrc_cmd->pdu),
1236                tran_status);
1237     return BT_STATUS_FAIL;
1238   }
1239 
1240   BT_HDR* p_msg = NULL;
1241   tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg);
1242   if (status == AVRC_STS_NO_ERROR && p_msg != NULL) {
1243     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
1244     log::verbose("{} msgreq being sent out with label: {}", dump_rc_pdu(avrc_cmd->pdu),
1245                  p_transaction->label);
1246     BTA_AvVendorCmd(p_dev->rc_handle, p_transaction->label, cmd_code, data_start, p_msg->len);
1247     status = BT_STATUS_SUCCESS;
1248     start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
1249   } else {
1250     log::error("failed to build command. status: 0x{:02x}", status);
1251     release_transaction(p_dev, p_transaction->label);
1252   }
1253   osi_free(p_msg);
1254   return (bt_status_t)status;
1255 }
1256 
1257 /***************************************************************************
1258  *
1259  * Function         build_and_send_browsing_cmd
1260  *
1261  * Description      Send a command to a device on the browsing channel
1262  *
1263  * Parameters       avrc_cmd: The command you're sending
1264  *                  p_dev: Device control block
1265  *
1266  * Returns          BT_STATUS_SUCCESS if command is issued successfully
1267  *                  otherwise BT_STATUS_FAIL
1268  *
1269  **************************************************************************/
build_and_send_browsing_cmd(tAVRC_COMMAND * avrc_cmd,btif_rc_device_cb_t * p_dev)1270 static bt_status_t build_and_send_browsing_cmd(tAVRC_COMMAND* avrc_cmd,
1271                                                btif_rc_device_cb_t* p_dev) {
1272   rc_transaction_t* p_transaction = NULL;
1273   rc_transaction_context_t context = {.rc_addr = p_dev->rc_addr,
1274                                       .label = MAX_LABEL,
1275                                       .opcode = AVRC_OP_BROWSE,
1276                                       .command = {.browse = {avrc_cmd->pdu}}};
1277 
1278   bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
1279   if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
1280     log::error("failed to get label, pdu_id={}, status=0x{:02x}", dump_rc_pdu(avrc_cmd->pdu),
1281                tran_status);
1282     return BT_STATUS_FAIL;
1283   }
1284 
1285   BT_HDR* p_msg = NULL;
1286   tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg);
1287   if (status != AVRC_STS_NO_ERROR) {
1288     log::error("failed to build command status {}", status);
1289     release_transaction(p_dev, p_transaction->label);
1290     return BT_STATUS_FAIL;
1291   }
1292 
1293   log::verbose("Send pdu_id={}, label={}", dump_rc_pdu(avrc_cmd->pdu), p_transaction->label);
1294   BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->label, AVRC_CMD_CTRL, p_msg);
1295   start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
1296   return BT_STATUS_SUCCESS;
1297 }
1298 
1299 /***************************************************************************
1300  *
1301  * Function         handle_get_capability_response
1302  *
1303  * Description      Handles the get_cap_response to populate company id info
1304  *                  and query the supported events.
1305  *                  Initiates Notification registration for events supported
1306  * Returns          None
1307  *
1308  **************************************************************************/
handle_get_capability_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CAPS_RSP * p_rsp)1309 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_CAPS_RSP* p_rsp) {
1310   int xx = 0;
1311   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1312 
1313   /* Todo: Do we need to retry on command timeout */
1314   if (p_rsp->status != AVRC_STS_NO_ERROR) {
1315     log::error("Error capability response: 0x{:02X}", p_rsp->status);
1316     return;
1317   }
1318 
1319   if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED) {
1320     btif_rc_supported_event_t* p_event;
1321 
1322     /* Todo: Check if list can be active when we hit here */
1323     p_dev->rc_supported_event_list = list_new(osi_free);
1324     for (xx = 0; xx < p_rsp->count; xx++) {
1325       /* Skip registering for Play position change notification */
1326       if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE) ||
1327           (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE) ||
1328           (p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_POS_CHANGED) ||
1329           (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE) ||
1330           (p_rsp->param.event_id[xx] == AVRC_EVT_NOW_PLAYING_CHANGE) ||
1331           (p_rsp->param.event_id[xx] == AVRC_EVT_ADDR_PLAYER_CHANGE) ||
1332           (p_rsp->param.event_id[xx] == AVRC_EVT_UIDS_CHANGE) ||
1333           (p_rsp->param.event_id[xx] == AVRC_EVT_AVAL_PLAYERS_CHANGE)) {
1334         p_event = (btif_rc_supported_event_t*)osi_malloc(sizeof(btif_rc_supported_event_t));
1335         p_event->event_id = p_rsp->param.event_id[xx];
1336         p_event->status = eNOT_REGISTERED;
1337         list_append(p_dev->rc_supported_event_list, p_event);
1338       }
1339     }
1340 
1341     // On occasion a remote device can intermittently send a poorly configured
1342     // packet with 0 capabilities. This check ensures the stack does not crash.
1343     // Typically the remote device will send a proper packet in the future and
1344     // continue operation.
1345     if (list_is_empty(p_dev->rc_supported_event_list)) {
1346       return;
1347     }
1348 
1349     p_event = (btif_rc_supported_event_t*)list_front(p_dev->rc_supported_event_list);
1350     if (p_event != NULL) {
1351       register_for_event_notification(p_event, p_dev);
1352     }
1353   } else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
1354     getcapabilities_cmd(AVRC_CAP_EVENTS_SUPPORTED, p_dev);
1355     log::verbose("AVRC_CAP_COMPANY_ID:");
1356     for (xx = 0; xx < p_rsp->count; xx++) {
1357       log::verbose("company_id: {}", p_rsp->param.company_id[xx]);
1358     }
1359   }
1360 }
1361 
rc_is_track_id_valid(tAVRC_UID uid)1362 static bool rc_is_track_id_valid(tAVRC_UID uid) {
1363   tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1364 
1365   if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0) {
1366     return false;
1367   } else {
1368     return true;
1369   }
1370 }
1371 
1372 /***************************************************************************
1373  *
1374  * Function         handle_notification_response
1375  *
1376  * Description      Main handler for notification responses to registered events
1377  *                  1. Register for unregistered event(in interim response path)
1378  *                  2. After registering for all supported events, start
1379  *                     retrieving application settings and values
1380  *                  3. Reregister for events on getting changed response
1381  *                  4. Run play status timer for getting position when the
1382  *                     status changes to playing
1383  *                  5. Get the Media details when the track change happens
1384  *                     or track change interim response is received with
1385  *                     valid track id
1386  *                  6. HAL callback for play status change and application
1387  *                     setting change
1388  * Returns          None
1389  *
1390  **************************************************************************/
handle_notification_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_REG_NOTIF_RSP * p_rsp)1391 static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_REG_NOTIF_RSP* p_rsp) {
1392   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1393 
1394   if (p_dev == NULL) {
1395     log::error("p_dev NULL");
1396     return;
1397   }
1398 
1399   if (btif_av_src_sink_coexist_enabled() && p_rsp->event_id == AVRC_EVT_VOLUME_CHANGE) {
1400     log::error("legacy TG don't handle absolute volume change. leave it to new avrcp");
1401     return;
1402   }
1403 
1404   const uint32_t* attr_list = get_requested_attributes_list(p_dev);
1405   const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
1406 
1407   if (pmeta_msg->code == AVRC_RSP_INTERIM) {
1408     btif_rc_supported_event_t* p_event;
1409     list_node_t* node;
1410 
1411     log::verbose("Interim response: 0x{:2X}", p_rsp->event_id);
1412     switch (p_rsp->event_id) {
1413       case AVRC_EVT_PLAY_STATUS_CHANGE:
1414         get_play_status_cmd(p_dev);
1415         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb,
1416                                         p_dev->rc_addr,
1417                                         (btrc_play_status_t)p_rsp->param.play_status));
1418         break;
1419 
1420       case AVRC_EVT_TRACK_CHANGE:
1421         if (rc_is_track_id_valid(p_rsp->param.track) != true) {
1422           break;
1423         } else {
1424           uint8_t* p_data = p_rsp->param.track;
1425           BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
1426           get_play_status_cmd(p_dev);
1427           get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1428         }
1429         break;
1430 
1431       case AVRC_EVT_APP_SETTING_CHANGE:
1432         break;
1433 
1434       case AVRC_EVT_NOW_PLAYING_CHANGE:
1435         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->now_playing_contents_changed_cb,
1436                                         p_dev->rc_addr));
1437         break;
1438 
1439       case AVRC_EVT_AVAL_PLAYERS_CHANGE:
1440         log::verbose("AVRC_EVT_AVAL_PLAYERS_CHANGE");
1441         do_in_jni_thread(
1442                 base::BindOnce(bt_rc_ctrl_callbacks->available_player_changed_cb, p_dev->rc_addr));
1443         break;
1444 
1445       case AVRC_EVT_ADDR_PLAYER_CHANGE:
1446         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->addressed_player_changed_cb,
1447                                         p_dev->rc_addr, p_rsp->param.addr_player.player_id));
1448         break;
1449 
1450       case AVRC_EVT_PLAY_POS_CHANGED:
1451         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb,
1452                                         p_dev->rc_addr, 0, p_rsp->param.play_pos));
1453 
1454         break;
1455       case AVRC_EVT_UIDS_CHANGE:
1456         break;
1457 
1458       case AVRC_EVT_TRACK_REACHED_END:
1459       case AVRC_EVT_TRACK_REACHED_START:
1460       case AVRC_EVT_BATTERY_STATUS_CHANGE:
1461       case AVRC_EVT_SYSTEM_STATUS_CHANGE:
1462       default:
1463         log::error("Unhandled interim response: 0x{:2X}", p_rsp->event_id);
1464         return;
1465     }
1466 
1467     list_foreach(p_dev->rc_supported_event_list, iterate_supported_event_list_for_interim_rsp,
1468                  &p_rsp->event_id);
1469 
1470     node = list_begin(p_dev->rc_supported_event_list);
1471 
1472     while (node != NULL) {
1473       p_event = (btif_rc_supported_event_t*)list_node(node);
1474       if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
1475         register_for_event_notification(p_event, p_dev);
1476         break;
1477       }
1478       node = list_next(node);
1479       p_event = NULL;
1480     }
1481     /* Registered for all events, we can request application settings */
1482     if (p_event == NULL && !p_dev->rc_app_settings.query_started) {
1483       /* we need to do this only if remote TG supports
1484        * player application settings
1485        */
1486       p_dev->rc_app_settings.query_started = true;
1487       if (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING) {
1488         list_player_app_setting_attrib_cmd(p_dev);
1489       } else {
1490         log::verbose("App setting not supported, complete procedure");
1491         rc_ctrl_procedure_complete(p_dev);
1492       }
1493     }
1494   } else if (pmeta_msg->code == AVRC_RSP_CHANGED) {
1495     btif_rc_supported_event_t* p_event;
1496     list_node_t* node;
1497 
1498     log::verbose("Notification completed: 0x{:2X}", p_rsp->event_id);
1499 
1500     node = list_begin(p_dev->rc_supported_event_list);
1501 
1502     while (node != NULL) {
1503       p_event = (btif_rc_supported_event_t*)list_node(node);
1504       if (p_event != NULL && p_event->event_id == p_rsp->event_id) {
1505         p_event->status = eNOT_REGISTERED;
1506         register_for_event_notification(p_event, p_dev);
1507         break;
1508       }
1509       node = list_next(node);
1510     }
1511 
1512     switch (p_rsp->event_id) {
1513       case AVRC_EVT_PLAY_STATUS_CHANGE:
1514         /* Start timer to get play status periodically
1515          * if the play state is playing.
1516          */
1517         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb,
1518                                         p_dev->rc_addr,
1519                                         (btrc_play_status_t)p_rsp->param.play_status));
1520 
1521         break;
1522 
1523       case AVRC_EVT_TRACK_CHANGE:
1524         if (rc_is_track_id_valid(p_rsp->param.track) != true) {
1525           break;
1526         } else {
1527           uint8_t* p_data = p_rsp->param.track;
1528           BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
1529           get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1530         }
1531         break;
1532 
1533       case AVRC_EVT_APP_SETTING_CHANGE: {
1534         btrc_player_settings_t app_settings;
1535         uint16_t xx;
1536 
1537         app_settings.num_attr = p_rsp->param.player_setting.num_attr;
1538         for (xx = 0; xx < app_settings.num_attr; xx++) {
1539           app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
1540           app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
1541         }
1542         do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
1543                                         p_dev->rc_addr, app_settings));
1544       } break;
1545 
1546       case AVRC_EVT_NOW_PLAYING_CHANGE:
1547         break;
1548 
1549       case AVRC_EVT_AVAL_PLAYERS_CHANGE:
1550         break;
1551 
1552       case AVRC_EVT_ADDR_PLAYER_CHANGE:
1553         break;
1554 
1555       case AVRC_EVT_PLAY_POS_CHANGED:
1556         // handle on interim
1557         break;
1558 
1559       case AVRC_EVT_UIDS_CHANGE:
1560         break;
1561 
1562       case AVRC_EVT_TRACK_REACHED_END:
1563       case AVRC_EVT_TRACK_REACHED_START:
1564       case AVRC_EVT_BATTERY_STATUS_CHANGE:
1565       case AVRC_EVT_SYSTEM_STATUS_CHANGE:
1566       default:
1567         log::error("Unhandled completion response: 0x{:2X}", p_rsp->event_id);
1568         return;
1569     }
1570   }
1571 }
1572 
1573 /***************************************************************************
1574  *
1575  * Function         handle_app_attr_response
1576  *
1577  * Description      handles the the application attributes response and
1578  *                  initiates procedure to fetch the attribute values
1579  * Returns          None
1580  *
1581  **************************************************************************/
handle_app_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_ATTR_RSP * p_rsp)1582 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_ATTR_RSP* p_rsp) {
1583   uint8_t xx;
1584   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1585 
1586   if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
1587     log::error("Error getting Player application settings: 0x{:2X}", p_rsp->status);
1588     rc_ctrl_procedure_complete(p_dev);
1589     return;
1590   }
1591   p_dev->rc_app_settings.num_attrs = 0;
1592   p_dev->rc_app_settings.num_ext_attrs = 0;
1593 
1594   for (xx = 0; xx < p_rsp->num_attr; xx++) {
1595     uint8_t st_index;
1596 
1597     if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT) {
1598       st_index = p_dev->rc_app_settings.num_ext_attrs;
1599       p_dev->rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
1600       p_dev->rc_app_settings.num_ext_attrs++;
1601     } else {
1602       st_index = p_dev->rc_app_settings.num_attrs;
1603       p_dev->rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
1604       p_dev->rc_app_settings.num_attrs++;
1605     }
1606   }
1607   p_dev->rc_app_settings.attr_index = 0;
1608   p_dev->rc_app_settings.ext_attr_index = 0;
1609   p_dev->rc_app_settings.ext_val_index = 0;
1610   if (p_rsp->num_attr) {
1611     list_player_app_setting_value_cmd(p_dev->rc_app_settings.attrs[0].attr_id, p_dev);
1612   } else {
1613     log::error("No Player application settings found");
1614   }
1615 }
1616 
1617 /***************************************************************************
1618  *
1619  * Function         handle_app_val_response
1620  *
1621  * Description      handles the the attributes value response and if extended
1622  *                  menu is available, it initiates query for the attribute
1623  *                  text. If not, it initiates procedure to get the current
1624  *                  attribute values and calls the HAL callback for provding
1625  *                  application settings information.
1626  * Returns          None
1627  *
1628  **************************************************************************/
handle_app_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_VALUES_RSP * p_rsp)1629 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_VALUES_RSP* p_rsp) {
1630   uint8_t xx, attr_index;
1631   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1632   btif_rc_player_app_settings_t* p_app_settings;
1633   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1634 
1635   /* Todo: Do we need to retry on command timeout */
1636   if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
1637     log::error("Error fetching attribute values: 0x{:02X}", p_rsp->status);
1638     return;
1639   }
1640 
1641   p_app_settings = &p_dev->rc_app_settings;
1642 
1643   if (p_app_settings->attr_index < p_app_settings->num_attrs) {
1644     attr_index = p_app_settings->attr_index;
1645     p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
1646     for (xx = 0; xx < p_rsp->num_val; xx++) {
1647       p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
1648     }
1649     attr_index++;
1650     p_app_settings->attr_index++;
1651     if (attr_index < p_app_settings->num_attrs) {
1652       list_player_app_setting_value_cmd(p_app_settings->attrs[p_app_settings->attr_index].attr_id,
1653                                         p_dev);
1654     } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
1655       attr_index = 0;
1656       p_app_settings->ext_attr_index = 0;
1657       list_player_app_setting_value_cmd(p_app_settings->ext_attrs[attr_index].attr_id, p_dev);
1658     } else {
1659       for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1660         attrs[xx] = p_app_settings->attrs[xx].attr_id;
1661       }
1662       get_player_app_setting_cmd(p_app_settings->num_attrs, attrs, p_dev);
1663       do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1664                                       p_dev->rc_addr, p_app_settings->num_attrs,
1665                                       p_app_settings->attrs, 0, nullptr));
1666     }
1667   } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
1668     attr_index = p_app_settings->ext_attr_index;
1669     p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
1670     for (xx = 0; xx < p_rsp->num_val; xx++) {
1671       p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
1672     }
1673     attr_index++;
1674     p_app_settings->ext_attr_index++;
1675     if (attr_index < p_app_settings->num_ext_attrs) {
1676       list_player_app_setting_value_cmd(
1677               p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id, p_dev);
1678     } else {
1679       uint8_t attr[AVRC_MAX_APP_ATTR_SIZE];
1680 
1681       for (uint8_t xx = 0; xx < p_app_settings->num_ext_attrs; xx++) {
1682         attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
1683       }
1684       get_player_app_setting_attr_text_cmd(attr, p_app_settings->num_ext_attrs, p_dev);
1685     }
1686   }
1687 }
1688 
1689 /***************************************************************************
1690  *
1691  * Function         handle_app_cur_val_response
1692  *
1693  * Description      handles the the get attributes value response.
1694  *
1695  * Returns          None
1696  *
1697  **************************************************************************/
handle_app_cur_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CUR_APP_VALUE_RSP * p_rsp)1698 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
1699                                         tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp) {
1700   btrc_player_settings_t app_settings;
1701   uint16_t xx;
1702   btif_rc_device_cb_t* p_dev = NULL;
1703 
1704   /* Todo: Do we need to retry on command timeout */
1705   if (p_rsp->status != AVRC_STS_NO_ERROR) {
1706     log::error("Error fetching current settings: 0x{:02X}", p_rsp->status);
1707     return;
1708   }
1709   p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1710   if (p_dev == NULL) {
1711     log::error("Error in getting Device Address");
1712     osi_free_and_reset((void**)&p_rsp->p_vals);
1713     return;
1714   }
1715 
1716   app_settings.num_attr = p_rsp->num_val;
1717 
1718   if (app_settings.num_attr > BTRC_MAX_APP_SETTINGS) {
1719     app_settings.num_attr = BTRC_MAX_APP_SETTINGS;
1720   }
1721 
1722   for (xx = 0; xx < app_settings.num_attr; xx++) {
1723     app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
1724     app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
1725   }
1726 
1727   do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
1728                                   p_dev->rc_addr, app_settings));
1729   /* Application settings are fetched only once for initial values
1730    * initiate anything that follows after RC procedure.
1731    * Defer it if browsing is supported till players query
1732    */
1733   rc_ctrl_procedure_complete(p_dev);
1734   osi_free_and_reset((void**)&p_rsp->p_vals);
1735 }
1736 
1737 /***************************************************************************
1738  *
1739  * Function         handle_app_attr_txt_response
1740  *
1741  * Description      handles the the get attributes text response, if fails
1742  *                  calls HAL callback with just normal settings and initiates
1743  *                  query for current settings else initiates query for value
1744  *                  text
1745  * Returns          None
1746  *
1747  **************************************************************************/
handle_app_attr_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)1748 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
1749                                          tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
1750   uint8_t xx;
1751   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
1752   btif_rc_player_app_settings_t* p_app_settings;
1753   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1754 
1755   if (p_dev == NULL) {
1756     log::error("p_dev NULL");
1757     return;
1758   }
1759 
1760   p_app_settings = &p_dev->rc_app_settings;
1761 
1762   /* Todo: Do we need to retry on command timeout */
1763   if (p_rsp->status != AVRC_STS_NO_ERROR) {
1764     uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1765 
1766     log::error("Error fetching attribute text: 0x{:02X}", p_rsp->status);
1767     /* Not able to fetch Text for extended Menu, skip the process
1768      * and cleanup used memory. Proceed to get the current settings
1769      * for standard attributes.
1770      */
1771     p_app_settings->num_ext_attrs = 0;
1772     for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1773       osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1774     }
1775     p_app_settings->ext_attr_index = 0;
1776 
1777     for (xx = 0; xx < p_app_settings->num_attrs && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1778       attrs[xx] = p_app_settings->attrs[xx].attr_id;
1779     }
1780 
1781     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1782                                     p_dev->rc_addr, p_app_settings->num_attrs,
1783                                     p_app_settings->attrs, 0, nullptr));
1784     get_player_app_setting_cmd(xx, attrs, p_dev);
1785 
1786     return;
1787   }
1788 
1789   for (xx = 0; xx < p_rsp->num_attr; xx++) {
1790     uint8_t x;
1791     for (x = 0; x < p_app_settings->num_ext_attrs && x < AVRC_MAX_APP_ATTR_SIZE; x++) {
1792       if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) {
1793         p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
1794         p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
1795         p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
1796         break;
1797       }
1798     }
1799   }
1800 
1801   for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val && xx < BTRC_MAX_APP_ATTR_SIZE; xx++) {
1802     vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
1803   }
1804   get_player_app_setting_value_text_cmd(vals, xx, p_dev);
1805 }
1806 
1807 /***************************************************************************
1808  *
1809  * Function         handle_app_attr_val_txt_response
1810  *
1811  * Description      handles the the get attributes value text response, if fails
1812  *                  calls HAL callback with just normal settings and initiates
1813  *                  query for current settings
1814  * Returns          None
1815  *
1816  **************************************************************************/
handle_app_attr_val_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)1817 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg,
1818                                              tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
1819   uint8_t xx, attr_index;
1820   uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
1821   uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1822   btif_rc_player_app_settings_t* p_app_settings;
1823   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1824 
1825   if (p_dev == NULL) {
1826     log::error("p_dev NULL");
1827     return;
1828   }
1829 
1830   p_app_settings = &p_dev->rc_app_settings;
1831 
1832   /* Todo: Do we need to retry on command timeout */
1833   if (p_rsp->status != AVRC_STS_NO_ERROR) {
1834     uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1835 
1836     log::error("Error fetching attribute value text: 0x{:02X}", p_rsp->status);
1837 
1838     /* Not able to fetch Text for extended Menu, skip the process
1839      * and cleanup used memory. Proceed to get the current settings
1840      * for standard attributes.
1841      */
1842     p_app_settings->num_ext_attrs = 0;
1843     for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1844       int x;
1845       btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
1846 
1847       for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1848         osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
1849       }
1850       p_ext_attr->num_val = 0;
1851       osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1852     }
1853     p_app_settings->ext_attr_index = 0;
1854 
1855     for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1856       attrs[xx] = p_app_settings->attrs[xx].attr_id;
1857     }
1858     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1859                                     p_dev->rc_addr, p_app_settings->num_attrs,
1860                                     p_app_settings->attrs, 0, nullptr));
1861 
1862     get_player_app_setting_cmd(xx, attrs, p_dev);
1863     return;
1864   }
1865 
1866   if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) {
1867     log::error("ext_val_index is 0x{:02x}, overflow!", p_app_settings->ext_val_index);
1868     return;
1869   }
1870 
1871   for (xx = 0; xx < p_rsp->num_attr; xx++) {
1872     uint8_t x;
1873     btrc_player_app_ext_attr_t* p_ext_attr;
1874     p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
1875     for (x = 0; x < p_rsp->num_attr && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1876       if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) {
1877         p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
1878         p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
1879         p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
1880         break;
1881       }
1882     }
1883   }
1884   p_app_settings->ext_val_index++;
1885 
1886   if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) {
1887     attr_index = p_app_settings->ext_val_index;
1888     for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++) {
1889       vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
1890     }
1891     get_player_app_setting_value_text_cmd(vals, xx, p_dev);
1892   } else {
1893     uint8_t x;
1894 
1895     for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1896       attrs[xx] = p_app_settings->attrs[xx].attr_id;
1897     }
1898     for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
1899       attrs[xx + x] = p_app_settings->ext_attrs[x].attr_id;
1900     }
1901     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1902                                     p_dev->rc_addr, p_app_settings->num_attrs,
1903                                     p_app_settings->attrs, p_app_settings->num_ext_attrs,
1904                                     p_app_settings->ext_attrs));
1905     get_player_app_setting_cmd(xx + x, attrs, p_dev);
1906 
1907     /* Free the application settings information after sending to
1908      * application.
1909      */
1910     do_in_jni_thread(base::BindOnce(cleanup_app_attr_val_txt_response, p_app_settings));
1911     p_app_settings->num_attrs = 0;
1912   }
1913 }
1914 
1915 /***************************************************************************
1916  *
1917  * Function         cleanup_app_attr_val_txt_response
1918  *
1919  * Description      Frees the memory that was allocated for reporting player
1920  *                  application settings.
1921  * Returns          None
1922  **************************************************************************/
cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t * p_app_settings)1923 static void cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t* p_app_settings) {
1924   for (uint8_t xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1925     int x;
1926     btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
1927     for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1928       osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
1929     }
1930     p_ext_attr->num_val = 0;
1931     osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1932   }
1933 }
1934 
1935 /***************************************************************************
1936  *
1937  * Function         handle_set_app_attr_val_response
1938  *
1939  * Description      handles the the set attributes value response, if fails
1940  *                  calls HAL callback to indicate the failure
1941  * Returns          None
1942  *
1943  **************************************************************************/
handle_set_app_attr_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP *)1944 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* /*p_rsp*/) {
1945   uint8_t accepted = 0;
1946   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1947 
1948   if (p_dev == NULL) {
1949     log::error("p_dev NULL");
1950     return;
1951   }
1952 
1953   /* For timeout pmeta_msg will be NULL, else we need to
1954    * check if this is accepted by TG
1955    */
1956   if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) {
1957     accepted = 1;
1958   }
1959   do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb, p_dev->rc_addr,
1960                                   accepted));
1961 }
1962 
1963 /***************************************************************************
1964  *
1965  * Function         handle_get_metadata_attr_response
1966  *
1967  * Description      handles the the element attributes response, calls
1968  *                  HAL callback to update track change information.
1969  * Returns          None
1970  *
1971  **************************************************************************/
handle_get_metadata_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ATTRS_RSP * p_rsp)1972 static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg,
1973                                               tAVRC_GET_ATTRS_RSP* p_rsp) {
1974   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1975 
1976   if (p_rsp->status == AVRC_STS_NO_ERROR) {
1977     size_t buf_size = p_rsp->num_attrs * sizeof(btrc_element_attr_val_t);
1978     btrc_element_attr_val_t* p_attr = (btrc_element_attr_val_t*)osi_calloc(buf_size);
1979 
1980     if (p_dev == NULL) {
1981       log::error("p_dev NULL");
1982       return;
1983     }
1984 
1985     for (int i = 0; i < p_rsp->num_attrs; i++) {
1986       p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
1987       /* Todo. Length limit check to include null */
1988       if (p_rsp->p_attrs[i].name.str_len && p_rsp->p_attrs[i].name.p_str) {
1989         memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str, p_rsp->p_attrs[i].name.str_len);
1990         osi_free_and_reset((void**)&p_rsp->p_attrs[i].name.p_str);
1991       }
1992     }
1993 
1994     osi_free_and_reset((void**)&p_rsp->p_attrs);
1995 
1996     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->track_changed_cb, p_dev->rc_addr,
1997                                     p_rsp->num_attrs, p_attr));
1998     do_in_jni_thread(base::BindOnce(osi_free, p_attr));
1999   } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
2000     /* Retry for timeout case, this covers error handling
2001      * for continuation failure also.
2002      */
2003     const uint32_t* attr_list = get_requested_attributes_list(p_dev);
2004     const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
2005     get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
2006   } else {
2007     log::error("Error in get element attr procedure: {}", p_rsp->status);
2008   }
2009 }
2010 
2011 /***************************************************************************
2012  *
2013  * Function         handle_get_playstatus_response
2014  *
2015  * Description      handles the the play status response, calls
2016  *                  HAL callback to update play position.
2017  * Returns          None
2018  *
2019  **************************************************************************/
handle_get_playstatus_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_PLAY_STATUS_RSP * p_rsp)2020 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
2021                                            tAVRC_GET_PLAY_STATUS_RSP* p_rsp) {
2022   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2023 
2024   if (p_dev == NULL) {
2025     log::error("p_dev NULL");
2026     return;
2027   }
2028 
2029   if (p_rsp->status == AVRC_STS_NO_ERROR) {
2030     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb, p_dev->rc_addr,
2031                                     (btrc_play_status_t)p_rsp->play_status));
2032     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb, p_dev->rc_addr,
2033                                     p_rsp->song_len, p_rsp->song_pos));
2034   } else {
2035     log::error("Error in get play status procedure: {}", p_rsp->status);
2036   }
2037 }
2038 
2039 /***************************************************************************
2040  *
2041  * Function         handle_set_addressed_player_response
2042  *
2043  * Description      handles the the set addressed player response, calls
2044  *                  HAL callback
2045  * Returns          None
2046  *
2047  **************************************************************************/
handle_set_addressed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP * p_rsp)2048 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* p_rsp) {
2049   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2050 
2051   if (p_dev == NULL) {
2052     log::error("p_dev NULL");
2053     return;
2054   }
2055 
2056   if (p_rsp->status == AVRC_STS_NO_ERROR) {
2057     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->set_addressed_player_cb, p_dev->rc_addr,
2058                                     p_rsp->status));
2059   } else {
2060     log::error("Error in get play status procedure {}", p_rsp->status);
2061   }
2062 }
2063 
2064 /***************************************************************************
2065  *
2066  * Function         handle_get_folder_items_response
2067  *
2068  * Description      handles the the get folder items response, calls
2069  *                  HAL callback to send the folder items.
2070  * Returns          None
2071  *
2072  **************************************************************************/
handle_get_folder_items_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ITEMS_RSP * p_rsp)2073 static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg,
2074                                              tAVRC_GET_ITEMS_RSP* p_rsp) {
2075   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2076 
2077   if (p_rsp->status == AVRC_STS_NO_ERROR) {
2078     /* Convert the internal folder listing into a response that can
2079      * be passed onto JNI via HAL_CBACK
2080      */
2081     uint8_t item_count = p_rsp->item_count;
2082     btrc_folder_items_t* btrc_items =
2083             (btrc_folder_items_t*)osi_malloc(sizeof(btrc_folder_items_t) * item_count);
2084     for (uint8_t i = 0; i < item_count; i++) {
2085       const tAVRC_ITEM* avrc_item = &(p_rsp->p_item_list[i]);
2086       btrc_folder_items_t* btrc_item = &(btrc_items[i]);
2087       log::verbose("folder item type {}", avrc_item->item_type);
2088       switch (avrc_item->item_type) {
2089         case AVRC_ITEM_MEDIA:
2090           log::verbose("setting type to {}", BTRC_ITEM_MEDIA);
2091           /* Allocate Space for Attributes */
2092           btrc_item->media.num_attrs = avrc_item->u.media.attr_count;
2093           btrc_item->media.p_attrs = (btrc_element_attr_val_t*)osi_malloc(
2094                   btrc_item->media.num_attrs * sizeof(btrc_element_attr_val_t));
2095           get_folder_item_type_media(avrc_item, btrc_item);
2096           break;
2097 
2098         case AVRC_ITEM_FOLDER:
2099           log::verbose("setting type to BTRC_ITEM_FOLDER");
2100           get_folder_item_type_folder(avrc_item, btrc_item);
2101           break;
2102 
2103         case AVRC_ITEM_PLAYER:
2104           log::verbose("setting type to BTRC_ITEM_PLAYER");
2105           get_folder_item_type_player(avrc_item, btrc_item);
2106           break;
2107 
2108         default:
2109           log::error("cannot understand folder item type {}", avrc_item->item_type);
2110       }
2111     }
2112 
2113     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
2114                                     BTRC_STS_NO_ERROR,
2115                                     /* We want to make the ownership explicit in native */
2116                                     btrc_items, item_count));
2117 
2118     if (item_count > 0) {
2119       if (btrc_items[0].item_type == AVRC_ITEM_PLAYER &&
2120           (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING)) {
2121         list_player_app_setting_attrib_cmd(p_dev);
2122       }
2123     }
2124     /* Release the memory block for items and attributes allocated here.
2125      * Since the executor for do_in_jni_thread is a Single Thread Task Runner it
2126      * is okay to queue up the cleanup of btrc_items */
2127     do_in_jni_thread(base::BindOnce(cleanup_btrc_folder_items, btrc_items, item_count));
2128 
2129     log::verbose("get_folder_items_cb sent to JNI thread");
2130   } else {
2131     log::error("Error {}", p_rsp->status);
2132     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
2133                                     (btrc_status_t)p_rsp->status, nullptr, 0));
2134   }
2135 }
2136 /***************************************************************************
2137  *
2138  * Function         cleanup_btrc_folder_items
2139  *
2140  * Description      Frees the memory that was allocated for a list of folder
2141  *                  items.
2142  * Returns          None
2143  **************************************************************************/
cleanup_btrc_folder_items(btrc_folder_items_t * btrc_items,uint8_t item_count)2144 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, uint8_t item_count) {
2145   for (uint8_t i = 0; i < item_count; i++) {
2146     btrc_folder_items_t* btrc_item = &(btrc_items[i]);
2147     switch (btrc_item->item_type) {
2148       case BTRC_ITEM_MEDIA:
2149         osi_free(btrc_item->media.p_attrs);
2150         break;
2151       case BTRC_ITEM_PLAYER:
2152       case BTRC_ITEM_FOLDER:
2153         /*Nothing to free*/
2154         break;
2155       default:
2156         log::warn("free unspecified type");
2157     }
2158   }
2159   osi_free(btrc_items);
2160 }
2161 
2162 /***************************************************************************
2163  *
2164  * Function         get_folder_item_type_media
2165  *
2166  * Description      Converts the AVRC representation of a folder item with
2167  *                  TYPE media to BTIF representation.
2168  * Returns          None
2169  *
2170  **************************************************************************/
get_folder_item_type_media(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2171 static void get_folder_item_type_media(const tAVRC_ITEM* avrc_item,
2172                                        btrc_folder_items_t* btrc_item) {
2173   btrc_item->item_type = BTRC_ITEM_MEDIA;
2174   const tAVRC_ITEM_MEDIA* avrc_item_media = &(avrc_item->u.media);
2175   btrc_item_media_t* btrc_item_media = &(btrc_item->media);
2176   /* UID */
2177   memset(btrc_item_media->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
2178   memcpy(btrc_item_media->uid, avrc_item_media->uid, sizeof(uint8_t) * BTRC_UID_SIZE);
2179 
2180   /* Audio/Video type */
2181   switch (avrc_item_media->type) {
2182     case AVRC_MEDIA_TYPE_AUDIO:
2183       btrc_item_media->type = BTRC_MEDIA_TYPE_AUDIO;
2184       break;
2185     case AVRC_MEDIA_TYPE_VIDEO:
2186       btrc_item_media->type = BTRC_MEDIA_TYPE_VIDEO;
2187       break;
2188   }
2189 
2190   /* Charset ID */
2191   btrc_item_media->charset_id = avrc_item_media->name.charset_id;
2192 
2193   /* Copy the name */
2194   log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, avrc_item_media->name.str_len);
2195   memset(btrc_item_media->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2196   memcpy(btrc_item_media->name, avrc_item_media->name.p_str,
2197          sizeof(uint8_t) * (avrc_item_media->name.str_len));
2198 
2199   /* Extract each attribute */
2200   for (int i = 0; i < avrc_item_media->attr_count; i++) {
2201     btrc_element_attr_val_t* btrc_attr_pair = &(btrc_item_media->p_attrs[i]);
2202     tAVRC_ATTR_ENTRY* avrc_attr_pair = &(avrc_item_media->p_attr_list[i]);
2203 
2204     log::verbose("media attr id 0x{:x}", avrc_attr_pair->attr_id);
2205 
2206     switch (avrc_attr_pair->attr_id) {
2207       case AVRC_MEDIA_ATTR_ID_TITLE:
2208         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TITLE;
2209         break;
2210       case AVRC_MEDIA_ATTR_ID_ARTIST:
2211         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ARTIST;
2212         break;
2213       case AVRC_MEDIA_ATTR_ID_ALBUM:
2214         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ALBUM;
2215         break;
2216       case AVRC_MEDIA_ATTR_ID_TRACK_NUM:
2217         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TRACK_NUM;
2218         break;
2219       case AVRC_MEDIA_ATTR_ID_NUM_TRACKS:
2220         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_NUM_TRACKS;
2221         break;
2222       case AVRC_MEDIA_ATTR_ID_GENRE:
2223         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_GENRE;
2224         break;
2225       case AVRC_MEDIA_ATTR_ID_PLAYING_TIME:
2226         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_PLAYING_TIME;
2227         break;
2228       case AVRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE:
2229         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE;
2230         break;
2231       default:
2232         log::error("invalid media attr id: 0x{:x}", avrc_attr_pair->attr_id);
2233         btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_INVALID;
2234     }
2235 
2236     memset(btrc_attr_pair->text, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2237     memcpy(btrc_attr_pair->text, avrc_attr_pair->name.p_str, avrc_attr_pair->name.str_len);
2238   }
2239 }
2240 
2241 /***************************************************************************
2242  *
2243  * Function         get_folder_item_type_folder
2244  *
2245  * Description      Converts the AVRC representation of a folder item with
2246  *                  TYPE folder to BTIF representation.
2247  * Returns          None
2248  *
2249  **************************************************************************/
get_folder_item_type_folder(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2250 static void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
2251                                         btrc_folder_items_t* btrc_item) {
2252   btrc_item->item_type = BTRC_ITEM_FOLDER;
2253   const tAVRC_ITEM_FOLDER* avrc_item_folder = &(avrc_item->u.folder);
2254   btrc_item_folder_t* btrc_item_folder = &(btrc_item->folder);
2255   /* Copy the UID */
2256   memset(btrc_item_folder->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
2257   memcpy(btrc_item_folder->uid, avrc_item_folder->uid, sizeof(uint8_t) * BTRC_UID_SIZE);
2258 
2259   /* Copy the type */
2260   switch (avrc_item_folder->type) {
2261     case AVRC_FOLDER_TYPE_MIXED:
2262       btrc_item_folder->type = BTRC_FOLDER_TYPE_MIXED;
2263       break;
2264     case AVRC_FOLDER_TYPE_TITLES:
2265       btrc_item_folder->type = BTRC_FOLDER_TYPE_TITLES;
2266       break;
2267     case AVRC_FOLDER_TYPE_ALNUMS:
2268       btrc_item_folder->type = BTRC_FOLDER_TYPE_ALBUMS;
2269       break;
2270     case AVRC_FOLDER_TYPE_ARTISTS:
2271       btrc_item_folder->type = BTRC_FOLDER_TYPE_ARTISTS;
2272       break;
2273     case AVRC_FOLDER_TYPE_GENRES:
2274       btrc_item_folder->type = BTRC_FOLDER_TYPE_GENRES;
2275       break;
2276     case AVRC_FOLDER_TYPE_PLAYLISTS:
2277       btrc_item_folder->type = BTRC_FOLDER_TYPE_PLAYLISTS;
2278       break;
2279     case AVRC_FOLDER_TYPE_YEARS:
2280       btrc_item_folder->type = BTRC_FOLDER_TYPE_YEARS;
2281       break;
2282   }
2283 
2284   /* Copy if playable */
2285   btrc_item_folder->playable = avrc_item_folder->playable;
2286 
2287   /* Copy name */
2288   log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, avrc_item_folder->name.str_len);
2289   memset(btrc_item_folder->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2290   memcpy(btrc_item_folder->name, avrc_item_folder->name.p_str,
2291          avrc_item_folder->name.str_len * sizeof(uint8_t));
2292 
2293   /* Copy charset */
2294   btrc_item_folder->charset_id = avrc_item_folder->name.charset_id;
2295 }
2296 
2297 /***************************************************************************
2298  *
2299  * Function         get_folder_item_type_player
2300  *
2301  * Description      Converts the AVRC representation of a folder item with
2302  *                  TYPE player to BTIF representation.
2303  * Returns          None
2304  *
2305  **************************************************************************/
get_folder_item_type_player(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2306 static void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
2307                                         btrc_folder_items_t* btrc_item) {
2308   btrc_item->item_type = BTRC_ITEM_PLAYER;
2309   const tAVRC_ITEM_PLAYER* avrc_item_player = &(avrc_item->u.player);
2310   btrc_item_player_t* btrc_item_player = &(btrc_item->player);
2311   /* Player ID */
2312   btrc_item_player->player_id = avrc_item_player->player_id;
2313   /* Major type */
2314   btrc_item_player->major_type = avrc_item_player->major_type;
2315   /* Sub type */
2316   btrc_item_player->sub_type = avrc_item_player->sub_type;
2317   /* Play status */
2318   btrc_item_player->play_status = avrc_item_player->play_status;
2319   /* Features */
2320   memcpy(btrc_item_player->features, avrc_item_player->features, BTRC_FEATURE_BIT_MASK_SIZE);
2321 
2322   memset(btrc_item_player->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2323   memcpy(btrc_item_player->name, avrc_item_player->name.p_str, avrc_item_player->name.str_len);
2324 }
2325 
2326 /***************************************************************************
2327  *
2328  * Function         handle_change_path_response
2329  *
2330  * Description      handles the the change path response, calls
2331  *                  HAL callback to send the updated folder
2332  * Returns          None
2333  *
2334  **************************************************************************/
handle_change_path_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_CHG_PATH_RSP * p_rsp)2335 static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_CHG_PATH_RSP* p_rsp) {
2336   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2337 
2338   if (p_dev == NULL) {
2339     log::error("Invalid rc handle");
2340     return;
2341   }
2342 
2343   if (p_rsp->status == AVRC_STS_NO_ERROR) {
2344     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->change_folder_path_cb, p_dev->rc_addr,
2345                                     p_rsp->num_items));
2346   } else {
2347     log::error("error in handle_change_path_response {}", p_rsp->status);
2348   }
2349 }
2350 
2351 /***************************************************************************
2352  *
2353  * Function         handle_set_browsed_player_response
2354  *
2355  * Description      handles the the change path response, calls
2356  *                  HAL callback to send the updated folder
2357  * Returns          None
2358  *
2359  **************************************************************************/
handle_set_browsed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_SET_BR_PLAYER_RSP * p_rsp)2360 static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg,
2361                                                tAVRC_SET_BR_PLAYER_RSP* p_rsp) {
2362   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2363 
2364   if (p_dev == NULL) {
2365     log::error("Invalid rc handle");
2366     return;
2367   }
2368 
2369   if (p_rsp->status == AVRC_STS_NO_ERROR) {
2370     do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr,
2371                                     p_rsp->num_items, p_rsp->folder_depth));
2372   } else {
2373     log::error("error {}", p_rsp->status);
2374   }
2375 }
2376 
2377 /***************************************************************************
2378  *
2379  * Function         clear_cmd_timeout
2380  *
2381  * Description      helper function to stop the command timeout timer
2382  * Returns          None
2383  *
2384  **************************************************************************/
clear_cmd_timeout(btif_rc_device_cb_t * p_dev,uint8_t label)2385 static void clear_cmd_timeout(btif_rc_device_cb_t* p_dev, uint8_t label) {
2386   rc_transaction_t* p_txn;
2387 
2388   p_txn = get_transaction_by_lbl(p_dev, label);
2389   if (p_txn == NULL) {
2390     log::error("Error in transaction label lookup");
2391     return;
2392   }
2393 
2394   if (p_txn->timer != NULL) {
2395     // Free also calls alarm_cancel() in its implementation
2396     alarm_free(p_txn->timer);
2397   }
2398   p_txn->timer = nullptr;
2399 }
2400 
2401 /***************************************************************************
2402  *
2403  * Function         handle_avk_rc_metamsg_rsp
2404  *
2405  * Description      Handle RC metamessage response
2406  *
2407  * Returns          void
2408  *
2409  **************************************************************************/
handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG * pmeta_msg)2410 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) {
2411   tAVRC_RESPONSE avrc_response = {0};
2412   uint8_t scratch_buf[512] = {0};  // this variable is unused
2413   uint16_t buf_len;
2414   tAVRC_STS status;
2415   btif_rc_device_cb_t* p_dev = NULL;
2416 
2417   log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
2418 
2419   p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2420   status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
2421   if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) &&
2422       (pmeta_msg->code <= AVRC_RSP_INTERIM)) {
2423     log::verbose("parse status {} pdu = {} rsp_status = {}", status, avrc_response.pdu,
2424                  pmeta_msg->p_msg->vendor.hdr.ctype);
2425 
2426     switch (avrc_response.pdu) {
2427       case AVRC_PDU_REGISTER_NOTIFICATION:
2428         handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
2429         if (pmeta_msg->code == AVRC_RSP_INTERIM) {
2430           /* Don't free the transaction Id */
2431           clear_cmd_timeout(p_dev, pmeta_msg->label);
2432           return;
2433         }
2434         break;
2435 
2436       case AVRC_PDU_GET_CAPABILITIES:
2437         handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
2438         break;
2439 
2440       case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2441         handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
2442         break;
2443 
2444       case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2445         handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
2446         break;
2447 
2448       case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2449         handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
2450         break;
2451 
2452       case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2453         handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
2454         break;
2455 
2456       case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2457         handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
2458         break;
2459 
2460       case AVRC_PDU_SET_PLAYER_APP_VALUE:
2461         handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
2462         break;
2463 
2464       case AVRC_PDU_GET_ELEMENT_ATTR:
2465         handle_get_metadata_attr_response(pmeta_msg, &avrc_response.get_attrs);
2466         break;
2467 
2468       case AVRC_PDU_GET_PLAY_STATUS:
2469         handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
2470         break;
2471 
2472       case AVRC_PDU_SET_ADDRESSED_PLAYER:
2473         handle_set_addressed_player_response(pmeta_msg, &avrc_response.rsp);
2474         break;
2475     }
2476   } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) {
2477     log::verbose("AVRC_OP_BROWSE pdu {}", avrc_response.pdu);
2478     /* check what kind of command it is for browsing */
2479     switch (avrc_response.pdu) {
2480       case AVRC_PDU_GET_FOLDER_ITEMS:
2481         handle_get_folder_items_response(pmeta_msg, &avrc_response.get_items);
2482         break;
2483       case AVRC_PDU_CHANGE_PATH:
2484         handle_change_path_response(pmeta_msg, &avrc_response.chg_path);
2485         break;
2486       case AVRC_PDU_SET_BROWSED_PLAYER:
2487         handle_set_browsed_player_response(pmeta_msg, &avrc_response.br_player);
2488         break;
2489       case AVRC_PDU_GET_ITEM_ATTRIBUTES:
2490         handle_get_metadata_attr_response(pmeta_msg, &avrc_response.get_attrs);
2491         break;
2492       default:
2493         log::error("cannot handle browse pdu {}", pmeta_msg->p_msg->hdr.opcode);
2494     }
2495   } else {
2496     log::verbose("Invalid Vendor Command code: {} len: {}. Not processing it.", pmeta_msg->code,
2497                  pmeta_msg->len);
2498     return;
2499   }
2500   log::verbose("release transaction {}", pmeta_msg->label);
2501   release_transaction(p_dev, pmeta_msg->label);
2502 }
2503 
2504 /***************************************************************************
2505  *
2506  * Function         handle_avk_rc_metamsg_cmd
2507  *
2508  * Description      Handle RC metamessage response
2509  *
2510  * Returns          void
2511  *
2512  **************************************************************************/
handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG * pmeta_msg)2513 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) {
2514   tAVRC_COMMAND avrc_cmd = {0};
2515   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2516   btif_rc_device_cb_t* p_dev = NULL;
2517 
2518   log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
2519   status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
2520   if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) {
2521     log::verbose("Received vendor command.code {}, PDU {} label {}", pmeta_msg->code, avrc_cmd.pdu,
2522                  pmeta_msg->label);
2523 
2524     if (status != AVRC_STS_NO_ERROR) {
2525       /* return error */
2526       log::warn("Error in parsing received metamsg command. status: 0x{:02x}", status);
2527       if (true == btif_av_both_enable()) {
2528         if (AVRC_PDU_GET_CAPABILITIES == avrc_cmd.pdu ||
2529             AVRC_PDU_GET_ELEMENT_ATTR == avrc_cmd.pdu || AVRC_PDU_GET_PLAY_STATUS == avrc_cmd.pdu ||
2530             AVRC_PDU_GET_FOLDER_ITEMS == avrc_cmd.pdu ||
2531             AVRC_PDU_GET_ITEM_ATTRIBUTES == avrc_cmd.pdu) {
2532           return;
2533         }
2534       }
2535       send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status,
2536                            pmeta_msg->p_msg->hdr.opcode);
2537     } else {
2538       p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2539       if (p_dev == NULL) {
2540         log::error("avk rc meta msg cmd for Invalid rc handle");
2541         return;
2542       }
2543 
2544       if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
2545         uint8_t event_id = avrc_cmd.reg_notif.event_id;
2546         log::verbose("Register notification event_id: {}", dump_rc_notification_event_id(event_id));
2547       } else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) {
2548         log::verbose("Abs Volume Cmd Recvd");
2549       }
2550 
2551       btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label, p_dev);
2552     }
2553   } else {
2554     log::verbose("Invalid Vendor Command  code: {} len: {}. Not processing it.", pmeta_msg->code,
2555                  pmeta_msg->len);
2556     return;
2557   }
2558 }
2559 
2560 /***************************************************************************
2561  *
2562  * Function         cleanup_ctrl
2563  *
2564  * Description      Closes the AVRC Controller interface
2565  *
2566  * Returns          void
2567  *
2568  **************************************************************************/
cleanup_ctrl()2569 static void cleanup_ctrl() {
2570   log::verbose("");
2571 
2572   if (bt_rc_ctrl_callbacks) {
2573     bt_rc_ctrl_callbacks = NULL;
2574   }
2575 
2576   for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
2577     alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer);
2578     memset(&btif_rc_cb.rc_multi_cb[idx], 0, sizeof(btif_rc_cb.rc_multi_cb[idx]));
2579   }
2580 
2581   memset(&btif_rc_cb.rc_multi_cb, 0, sizeof(btif_rc_cb.rc_multi_cb));
2582   log::verbose("completed");
2583 }
2584 
2585 /***************************************************************************
2586  *
2587  * Function         getcapabilities_cmd
2588  *
2589  * Description      GetCapabilties from Remote(Company_ID, Events_Supported)
2590  *
2591  * Returns          void
2592  *
2593  **************************************************************************/
getcapabilities_cmd(uint8_t cap_id,btif_rc_device_cb_t * p_dev)2594 static bt_status_t getcapabilities_cmd(uint8_t cap_id, btif_rc_device_cb_t* p_dev) {
2595   log::verbose("cap_id: {}", cap_id);
2596   CHECK_RC_CONNECTED(p_dev);
2597 
2598   tAVRC_COMMAND avrc_cmd = {0};
2599   avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
2600   avrc_cmd.get_caps.capability_id = cap_id;
2601   avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
2602   avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
2603 
2604   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2605 }
2606 
2607 /***************************************************************************
2608  *
2609  * Function         list_player_app_setting_attrib_cmd
2610  *
2611  * Description      Get supported List Player Attributes
2612  *
2613  * Returns          void
2614  *
2615  **************************************************************************/
list_player_app_setting_attrib_cmd(btif_rc_device_cb_t * p_dev)2616 static bt_status_t list_player_app_setting_attrib_cmd(btif_rc_device_cb_t* p_dev) {
2617   log::verbose("");
2618   CHECK_RC_CONNECTED(p_dev);
2619 
2620   tAVRC_COMMAND avrc_cmd = {0};
2621   avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
2622   avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
2623   avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
2624 
2625   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2626 }
2627 
2628 /***************************************************************************
2629  *
2630  * Function         list_player_app_setting_value_cmd
2631  *
2632  * Description      Get values of supported Player Attributes
2633  *
2634  * Returns          void
2635  *
2636  **************************************************************************/
list_player_app_setting_value_cmd(uint8_t attrib_id,btif_rc_device_cb_t * p_dev)2637 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id,
2638                                                      btif_rc_device_cb_t* p_dev) {
2639   log::verbose("attrib_id: {}", attrib_id);
2640   CHECK_RC_CONNECTED(p_dev);
2641 
2642   tAVRC_COMMAND avrc_cmd = {0};
2643   avrc_cmd.list_app_values.attr_id = attrib_id;
2644   avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
2645   avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
2646   avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
2647 
2648   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2649 }
2650 
2651 /***************************************************************************
2652  *
2653  * Function         get_player_app_setting_cmd
2654  *
2655  * Description      Get current values of Player Attributes
2656  *
2657  * Returns          void
2658  *
2659  **************************************************************************/
get_player_app_setting_cmd(uint8_t num_attrib,uint8_t * attrib_ids,btif_rc_device_cb_t * p_dev)2660 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids,
2661                                               btif_rc_device_cb_t* p_dev) {
2662   log::verbose("num_attrib: {}", num_attrib);
2663   CHECK_RC_CONNECTED(p_dev);
2664 
2665   tAVRC_COMMAND avrc_cmd = {0};
2666   avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
2667   avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
2668   avrc_cmd.get_cur_app_val.num_attr = num_attrib;
2669   avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
2670 
2671   for (int count = 0; count < num_attrib; count++) {
2672     avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
2673   }
2674 
2675   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2676 }
2677 
2678 /***************************************************************************
2679  *
2680  * Function         get_current_metadata_cmd
2681  *
2682  * Description      Fetch the current track metadata for the device
2683  *
2684  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2685  *                  BT_STATUS_FAIL.
2686  *
2687  **************************************************************************/
get_current_metadata_cmd(const RawAddress & bd_addr)2688 static bt_status_t get_current_metadata_cmd(const RawAddress& bd_addr) {
2689   log::verbose("");
2690   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2691   if (p_dev == NULL) {
2692     log::error("p_dev NULL");
2693     return BT_STATUS_DEVICE_NOT_FOUND;
2694   }
2695   const uint32_t* attr_list = get_requested_attributes_list(p_dev);
2696   const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
2697   return get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
2698 }
2699 
2700 /***************************************************************************
2701  *
2702  * Function         get_playback_state_cmd
2703  *
2704  * Description      Fetch the current playback state for the device
2705  *
2706  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2707  *                  BT_STATUS_FAIL.
2708  *
2709  **************************************************************************/
get_playback_state_cmd(const RawAddress & bd_addr)2710 static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) {
2711   log::verbose("");
2712   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2713   return get_play_status_cmd(p_dev);
2714 }
2715 
2716 /***************************************************************************
2717  *
2718  * Function         get_now_playing_list_cmd
2719  *
2720  * Description      Fetch the now playing list
2721  *
2722  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
2723  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
2724  *
2725  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2726  *                  BT_STATUS_FAIL.
2727  *
2728  **************************************************************************/
get_now_playing_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2729 static bt_status_t get_now_playing_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2730                                             uint32_t end_item) {
2731   log::verbose("start, end: ({}, {})", start_item, end_item);
2732   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_NOW_PLAYING, start_item, end_item);
2733 }
2734 
2735 /***************************************************************************
2736  *
2737  * Function         get_item_attribute_cmd
2738  *
2739  * Description      Fetch the item attributes for a given uid.
2740  *
2741  * Parameters       uid: Track UID you want attributes for
2742  *                  scope: Constant representing which scope you're querying
2743  *                         (i.e AVRC_SCOPE_FILE_SYSTEM)
2744  *                  p_dev: Device control block
2745  *
2746  * Returns          BT_STATUS_SUCCESS if command is issued successfully
2747  *                  otherwise BT_STATUS_FAIL
2748  *
2749  **************************************************************************/
get_item_attribute_cmd(uint64_t uid,int scope,uint8_t,const uint32_t *,btif_rc_device_cb_t * p_dev)2750 static bt_status_t get_item_attribute_cmd(uint64_t uid, int scope, uint8_t /*num_attribute*/,
2751                                           const uint32_t* /*p_attr_ids*/,
2752                                           btif_rc_device_cb_t* p_dev) {
2753   tAVRC_COMMAND avrc_cmd = {0};
2754   avrc_cmd.pdu = AVRC_PDU_GET_ITEM_ATTRIBUTES;
2755   avrc_cmd.get_attrs.scope = scope;
2756   memcpy(avrc_cmd.get_attrs.uid, &uid, 8);
2757   avrc_cmd.get_attrs.uid_counter = 0;
2758   avrc_cmd.get_attrs.attr_count = 0;
2759 
2760   return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2761 }
2762 
2763 /***************************************************************************
2764  *
2765  * Function         get_folder_list_cmd
2766  *
2767  * Description      Fetch the currently selected folder list
2768  *
2769  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
2770  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
2771  *
2772  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2773  *                  BT_STATUS_FAIL.
2774  *
2775  **************************************************************************/
get_folder_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2776 static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2777                                        uint32_t end_item) {
2778   log::verbose("start, end: ({}, {})", start_item, end_item);
2779   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item, end_item);
2780 }
2781 
2782 /***************************************************************************
2783  *
2784  * Function         get_player_list_cmd
2785  *
2786  * Description      Fetch the player list
2787  *
2788  * Paramters        start_item: First item to fetch (0 to fetch from beganning)
2789  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
2790  *
2791  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2792  *                  BT_STATUS_FAIL.
2793  *
2794  **************************************************************************/
get_player_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2795 static bt_status_t get_player_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2796                                        uint32_t end_item) {
2797   log::verbose("start, end: ({}, {})", start_item, end_item);
2798   return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item, end_item);
2799 }
2800 
2801 /***************************************************************************
2802  *
2803  * Function         change_folder_path_cmd
2804  *
2805  * Description      Change the folder.
2806  *
2807  * Paramters        direction: Direction (Up/Down) to change folder
2808  *                  uid: The UID of folder to move to
2809  *                  start_item: First item to fetch (0 to fetch from beganning)
2810  *                  end_item: Last item to fetch (0xffffffff to fetch until end)
2811  *
2812  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2813  *                  BT_STATUS_FAIL.
2814  *
2815  **************************************************************************/
change_folder_path_cmd(const RawAddress & bd_addr,uint8_t direction,uint8_t * uid)2816 static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr, uint8_t direction,
2817                                           uint8_t* uid) {
2818   log::verbose("direction {}", direction);
2819   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2820   CHECK_RC_CONNECTED(p_dev);
2821   CHECK_BR_CONNECTED(p_dev);
2822 
2823   tAVRC_COMMAND avrc_cmd = {0};
2824 
2825   avrc_cmd.chg_path.pdu = AVRC_PDU_CHANGE_PATH;
2826   avrc_cmd.chg_path.status = AVRC_STS_NO_ERROR;
2827   // TODO(sanketa): Improve for database aware clients.
2828   avrc_cmd.chg_path.uid_counter = 0;
2829   avrc_cmd.chg_path.direction = direction;
2830 
2831   memset(avrc_cmd.chg_path.folder_uid, 0, AVRC_UID_SIZE * sizeof(uint8_t));
2832   memcpy(avrc_cmd.chg_path.folder_uid, uid, AVRC_UID_SIZE * sizeof(uint8_t));
2833 
2834   return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2835 }
2836 
2837 /***************************************************************************
2838  *
2839  * Function         set_browsed_player_cmd
2840  *
2841  * Description      Change the browsed player.
2842  *
2843  * Paramters        id: The UID of player to move to
2844  *
2845  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2846  *                  BT_STATUS_FAIL.
2847  *
2848  **************************************************************************/
set_browsed_player_cmd(const RawAddress & bd_addr,uint16_t id)2849 static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr, uint16_t id) {
2850   log::verbose("id {}", id);
2851   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2852   CHECK_RC_CONNECTED(p_dev);
2853   CHECK_BR_CONNECTED(p_dev);
2854 
2855   tAVRC_COMMAND avrc_cmd = {0};
2856   avrc_cmd.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER;
2857   avrc_cmd.br_player.status = AVRC_STS_NO_ERROR;
2858   // TODO(sanketa): Improve for database aware clients.
2859   avrc_cmd.br_player.player_id = id;
2860 
2861   return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2862 }
2863 
2864 /***************************************************************************
2865  **
2866  ** Function         set_addressed_player_cmd
2867  **
2868  ** Description      Change the addressed player.
2869  **
2870  ** Paramters        id: The UID of player to move to
2871  **
2872  ** Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2873  **                  BT_STATUS_FAIL.
2874  **
2875  ***************************************************************************/
set_addressed_player_cmd(const RawAddress & bd_addr,uint16_t id)2876 static bt_status_t set_addressed_player_cmd(const RawAddress& bd_addr, uint16_t id) {
2877   log::verbose("id {}", id);
2878 
2879   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2880   CHECK_RC_CONNECTED(p_dev);
2881   CHECK_BR_CONNECTED(p_dev);
2882 
2883   tAVRC_COMMAND avrc_cmd = {0};
2884   avrc_cmd.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER;
2885   avrc_cmd.addr_player.status = AVRC_STS_NO_ERROR;
2886   // TODO(sanketa): Improve for database aware clients.
2887   avrc_cmd.addr_player.player_id = id;
2888 
2889   return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2890 }
2891 
2892 /***************************************************************************
2893  *
2894  * Function         get_folder_items_cmd
2895  *
2896  * Description      Helper function to browse the content hierarchy of the
2897  *                  TG device.
2898  *
2899  * Paramters        scope: AVRC_SCOPE_NOW_PLAYING (etc) for various browseable
2900  *                  content
2901  *                  start_item: First item to fetch (0 to fetch from beganning)
2902  *                  end_item: Last item to fetch (0xffff to fetch until end)
2903  *
2904  * Returns          BT_STATUS_SUCCESS if command issued successfully otherwise
2905  *                  BT_STATUS_FAIL.
2906  *
2907  **************************************************************************/
get_folder_items_cmd(const RawAddress & bd_addr,uint8_t scope,uint32_t start_item,uint32_t end_item)2908 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, uint8_t scope,
2909                                         uint32_t start_item, uint32_t end_item) {
2910   /* Check that both avrcp and browse channel are connected. */
2911   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2912   log::verbose("");
2913   CHECK_RC_CONNECTED(p_dev);
2914   CHECK_BR_CONNECTED(p_dev);
2915 
2916   tAVRC_COMMAND avrc_cmd = {0};
2917 
2918   /* Set the layer specific to point to browse although this should really
2919    * be done by lower layers and looking at the PDU
2920    */
2921   avrc_cmd.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS;
2922   avrc_cmd.get_items.status = AVRC_STS_NO_ERROR;
2923   avrc_cmd.get_items.scope = scope;
2924   avrc_cmd.get_items.start_item = start_item;
2925   avrc_cmd.get_items.end_item = end_item;
2926   avrc_cmd.get_items.attr_count = 0; /* p_attr_list does not matter hence */
2927 
2928   return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2929 }
2930 
2931 /***************************************************************************
2932  *
2933  * Function         change_player_app_setting
2934  *
2935  * Description      Set current values of Player Attributes
2936  *
2937  * Returns          void
2938  *
2939  **************************************************************************/
change_player_app_setting(const RawAddress & bd_addr,uint8_t num_attrib,uint8_t * attrib_ids,uint8_t * attrib_vals)2940 static bt_status_t change_player_app_setting(const RawAddress& bd_addr, uint8_t num_attrib,
2941                                              uint8_t* attrib_ids, uint8_t* attrib_vals) {
2942   log::verbose("num_attrib: {}", num_attrib);
2943   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2944   CHECK_RC_CONNECTED(p_dev);
2945 
2946   tAVRC_COMMAND avrc_cmd = {0};
2947   avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
2948   avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
2949   avrc_cmd.set_app_val.num_val = num_attrib;
2950   avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
2951   avrc_cmd.set_app_val.p_vals =
2952           (tAVRC_APP_SETTING*)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
2953   for (int count = 0; count < num_attrib; count++) {
2954     avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
2955     avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
2956   }
2957 
2958   bt_status_t st = build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
2959   osi_free_and_reset((void**)&avrc_cmd.set_app_val.p_vals);
2960   return st;
2961 }
2962 
2963 /***************************************************************************
2964  *
2965  * Function         play_item_cmd
2966  *
2967  * Description      Play the item specified by UID & scope
2968  *
2969  * Returns          void
2970  *
2971  **************************************************************************/
play_item_cmd(const RawAddress & bd_addr,uint8_t scope,uint8_t * uid,uint16_t uid_counter)2972 static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope, uint8_t* uid,
2973                                  uint16_t uid_counter) {
2974   log::verbose("scope {} uid_counter {}", scope, uid_counter);
2975   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2976   CHECK_RC_CONNECTED(p_dev);
2977   CHECK_BR_CONNECTED(p_dev);
2978 
2979   tAVRC_COMMAND avrc_cmd = {0};
2980   avrc_cmd.pdu = AVRC_PDU_PLAY_ITEM;
2981   avrc_cmd.play_item.opcode = AVRC_OP_VENDOR;
2982   avrc_cmd.play_item.status = AVRC_STS_NO_ERROR;
2983   avrc_cmd.play_item.scope = scope;
2984   memcpy(avrc_cmd.play_item.uid, uid, AVRC_UID_SIZE);
2985   avrc_cmd.play_item.uid_counter = uid_counter;
2986 
2987   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
2988 }
2989 
2990 /***************************************************************************
2991  *
2992  * Function         get_player_app_setting_attr_text_cmd
2993  *
2994  * Description      Get text description for app attribute
2995  *
2996  * Returns          void
2997  *
2998  **************************************************************************/
get_player_app_setting_attr_text_cmd(uint8_t * attrs,uint8_t num_attrs,btif_rc_device_cb_t * p_dev)2999 static bt_status_t get_player_app_setting_attr_text_cmd(uint8_t* attrs, uint8_t num_attrs,
3000                                                         btif_rc_device_cb_t* p_dev) {
3001   log::verbose("num attrs: {}", num_attrs);
3002   CHECK_RC_CONNECTED(p_dev);
3003 
3004   tAVRC_COMMAND avrc_cmd = {0};
3005   avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3006   avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3007   avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3008 
3009   for (int count = 0; count < num_attrs; count++) {
3010     avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3011   }
3012 
3013   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3014 }
3015 
3016 /***************************************************************************
3017  *
3018  * Function         get_player_app_setting_val_text_cmd
3019  *
3020  * Description      Get text description for app attribute values
3021  *
3022  * Returns          void
3023  *
3024  **************************************************************************/
get_player_app_setting_value_text_cmd(uint8_t * vals,uint8_t num_vals,btif_rc_device_cb_t * p_dev)3025 static bt_status_t get_player_app_setting_value_text_cmd(uint8_t* vals, uint8_t num_vals,
3026                                                          btif_rc_device_cb_t* p_dev) {
3027   log::verbose("num_vals: {}", num_vals);
3028   CHECK_RC_CONNECTED(p_dev);
3029 
3030   tAVRC_COMMAND avrc_cmd = {0};
3031   avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3032   avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3033   avrc_cmd.get_app_val_txt.num_val = num_vals;
3034 
3035   for (int count = 0; count < num_vals; count++) {
3036     avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3037   }
3038 
3039   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3040 }
3041 
3042 /***************************************************************************
3043  *
3044  * Function         register_notification_cmd
3045  *
3046  * Description      Send Command to register for a Notification ID
3047  *
3048  * Returns          void
3049  *
3050  **************************************************************************/
register_notification_cmd(uint8_t event_id,uint32_t event_value,btif_rc_device_cb_t * p_dev)3051 static bt_status_t register_notification_cmd(uint8_t event_id, uint32_t event_value,
3052                                              btif_rc_device_cb_t* p_dev) {
3053   log::verbose("event_id: {} event_value {}", event_id, event_value);
3054   CHECK_RC_CONNECTED(p_dev);
3055 
3056   tAVRC_COMMAND avrc_cmd = {0};
3057   avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3058   avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3059   avrc_cmd.reg_notif.event_id = event_id;
3060   avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3061   avrc_cmd.reg_notif.param = event_value;
3062 
3063   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_NOTIF, p_dev);
3064 }
3065 
3066 /***************************************************************************
3067  *
3068  * Function         get_metadata_attribute_cmd
3069  *
3070  * Description      Get metadata attributes for attributeIds. This function
3071  *                  will make the right determination of whether to use the
3072  *                  control or browsing channel for the request
3073  *
3074  * Returns          BT_STATUS_SUCCESS if the command is successfully issued
3075  *                  otherwise BT_STATUS_FAIL
3076  *
3077  **************************************************************************/
get_metadata_attribute_cmd(uint8_t num_attribute,const uint32_t * p_attr_ids,btif_rc_device_cb_t * p_dev)3078 static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
3079                                               btif_rc_device_cb_t* p_dev) {
3080   log::verbose("num_attribute: {} attribute_id: {}", num_attribute, p_attr_ids[0]);
3081 
3082   // If browsing is connected then send the command out that channel
3083   if (p_dev->br_connected) {
3084     return get_item_attribute_cmd(p_dev->rc_playing_uid, AVRC_SCOPE_NOW_PLAYING, num_attribute,
3085                                   p_attr_ids, p_dev);
3086   }
3087 
3088   // Otherwise, default to the control channel
3089   return get_element_attribute_cmd(num_attribute, p_attr_ids, p_dev);
3090 }
3091 
3092 /***************************************************************************
3093  *
3094  * Function         get_element_attribute_cmd
3095  *
3096  * Description      Get Element Attribute for  attributeIds
3097  *
3098  * Returns          void
3099  *
3100  **************************************************************************/
get_element_attribute_cmd(uint8_t num_attribute,const uint32_t * p_attr_ids,btif_rc_device_cb_t * p_dev)3101 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
3102                                              btif_rc_device_cb_t* p_dev) {
3103   log::verbose("num_attribute: {} attribute_id: {}", num_attribute, p_attr_ids[0]);
3104   CHECK_RC_CONNECTED(p_dev);
3105   tAVRC_COMMAND avrc_cmd = {0};
3106   avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3107   avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3108   avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3109   avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3110   for (int count = 0; count < num_attribute; count++) {
3111     avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3112   }
3113 
3114   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3115 }
3116 
3117 /***************************************************************************
3118  *
3119  * Function         get_play_status_cmd
3120  *
3121  * Description      Get Playing Status of a Device
3122  *
3123  * Returns          bt_status_t
3124  *
3125  **************************************************************************/
get_play_status_cmd(btif_rc_device_cb_t * p_dev)3126 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev) {
3127   log::verbose("");
3128   CHECK_RC_CONNECTED(p_dev);
3129 
3130   tAVRC_COMMAND avrc_cmd = {0};
3131   avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3132   avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3133   avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3134 
3135   return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3136 }
3137 
3138 /***************************************************************************
3139  *
3140  * Function         set_volume_rsp
3141  *
3142  * Description      Rsp for SetAbsoluteVolume Command
3143  *
3144  * Returns          void
3145  *
3146  **************************************************************************/
set_volume_rsp(const RawAddress & bd_addr,uint8_t abs_vol,uint8_t label)3147 static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol, uint8_t label) {
3148   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3149   tAVRC_RESPONSE avrc_rsp;
3150   BT_HDR* p_msg = NULL;
3151   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3152 
3153   CHECK_RC_CONNECTED(p_dev);
3154 
3155   log::verbose("abs_vol: {}", abs_vol);
3156 
3157   avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3158   avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3159   avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3160   avrc_rsp.volume.volume = abs_vol;
3161   status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
3162   if (status == AVRC_STS_NO_ERROR) {
3163     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
3164     log::verbose("msgreq being sent out with label: {}", p_dev->rc_vol_label);
3165     if (p_msg != NULL) {
3166       BTA_AvVendorRsp(p_dev->rc_handle, label, AVRC_RSP_ACCEPT, data_start, p_msg->len, 0);
3167       status = BT_STATUS_SUCCESS;
3168     }
3169   } else {
3170     log::error("failed to build command. status: 0x{:02x}", status);
3171   }
3172   osi_free(p_msg);
3173   return (bt_status_t)status;
3174 }
3175 
3176 /***************************************************************************
3177  *
3178  * Function         send_register_abs_vol_rsp
3179  *
3180  * Description      Rsp for Notification of Absolute Volume
3181  *
3182  * Returns          void
3183  *
3184  **************************************************************************/
volume_change_notification_rsp(const RawAddress & bd_addr,btrc_notification_type_t rsp_type,uint8_t abs_vol,uint8_t label)3185 static bt_status_t volume_change_notification_rsp(const RawAddress& bd_addr,
3186                                                   btrc_notification_type_t rsp_type,
3187                                                   uint8_t abs_vol, uint8_t label) {
3188   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3189   tAVRC_RESPONSE avrc_rsp;
3190   BT_HDR* p_msg = NULL;
3191   log::verbose("rsp_type: {} abs_vol: {}", rsp_type, abs_vol);
3192 
3193   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3194 
3195   CHECK_RC_CONNECTED(p_dev);
3196 
3197   avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3198   avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3199   avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3200   avrc_rsp.reg_notif.param.volume = abs_vol;
3201   avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3202 
3203   status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
3204   if (status == AVRC_STS_NO_ERROR) {
3205     log::verbose("msgreq being sent out with label: {}", label);
3206     uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
3207     BTA_AvVendorRsp(
3208             p_dev->rc_handle, label,
3209             (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ? AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3210             data_start, p_msg->len, 0);
3211     status = BT_STATUS_SUCCESS;
3212   } else {
3213     log::error("failed to build command. status: 0x{:02x}", status);
3214   }
3215   osi_free(p_msg);
3216 
3217   return (bt_status_t)status;
3218 }
3219 
3220 /***************************************************************************
3221  *
3222  * Function         send_groupnavigation_cmd
3223  *
3224  * Description      Send Pass-Through command
3225  *
3226  * Returns          void
3227  *
3228  **************************************************************************/
send_groupnavigation_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)3229 static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr, uint8_t key_code,
3230                                             uint8_t key_state) {
3231   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3232   rc_transaction_t* p_transaction = NULL;
3233   log::verbose("key-code: {}, key-state: {}", key_code, key_state);
3234   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3235 
3236   CHECK_RC_CONNECTED(p_dev);
3237 
3238   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
3239     rc_transaction_context_t context = {
3240             .rc_addr = p_dev->rc_addr,
3241             .label = MAX_LABEL,
3242             .opcode = AVRC_OP_PASS_THRU,
3243             .command = {.passthru = {AVRC_ID_VENDOR, key_state, key_code}}};
3244     bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
3245     if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3246       uint8_t buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3247       uint8_t* start = buffer;
3248       UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3249       *(start)++ = 0;
3250       UINT8_TO_BE_STREAM(start, key_code);
3251       BTA_AvRemoteVendorUniqueCmd(p_dev->rc_handle, p_transaction->label, (tBTA_AV_STATE)key_state,
3252                                   buffer, AVRC_PASS_THRU_GROUP_LEN);
3253       status = BT_STATUS_SUCCESS;
3254       start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
3255       log::verbose("Send command, key-code={}, key-state={}, label={}", key_code, key_state,
3256                    p_transaction->label);
3257     } else {
3258       status = BT_STATUS_FAIL;
3259       log::error("failed to get label, key-code={}, key-state={}, status={}", key_code, key_state,
3260                  tran_status);
3261     }
3262   } else {
3263     status = BT_STATUS_UNSUPPORTED;
3264     log::verbose("feature not supported");
3265   }
3266   return (bt_status_t)status;
3267 }
3268 
3269 /***************************************************************************
3270  *
3271  * Function         send_passthrough_cmd
3272  *
3273  * Description      Send Pass-Through command
3274  *
3275  * Returns          void
3276  *
3277  **************************************************************************/
send_passthrough_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)3278 static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr, uint8_t key_code,
3279                                         uint8_t key_state) {
3280   tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3281   btif_rc_device_cb_t* p_dev = NULL;
3282   log::error("calling btif_rc_get_device_by_bda");
3283   p_dev = btif_rc_get_device_by_bda(bd_addr);
3284 
3285   CHECK_RC_CONNECTED(p_dev);
3286 
3287   rc_transaction_t* p_transaction = NULL;
3288   log::verbose("key-code: {}, key-state: {}", key_code, key_state);
3289   if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
3290     rc_transaction_context_t context = {
3291             .rc_addr = p_dev->rc_addr,
3292             .label = MAX_LABEL,
3293             .opcode = AVRC_OP_PASS_THRU,
3294             .command = {.passthru = {AVRC_ID_VENDOR, key_state, key_code}}};
3295     bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
3296     if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) {
3297       BTA_AvRemoteCmd(p_dev->rc_handle, p_transaction->label, (tBTA_AV_RC)key_code,
3298                       (tBTA_AV_STATE)key_state);
3299       status = BT_STATUS_SUCCESS;
3300       start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
3301       log::verbose("Send command, key-code={}, key-state={}, label={}", key_code, key_state,
3302                    p_transaction->label);
3303     } else {
3304       status = BT_STATUS_FAIL;
3305       log::error("failed to get label, key-code={}, key-state={}, status={}", key_code, key_state,
3306                  tran_status);
3307     }
3308   } else {
3309     status = BT_STATUS_UNSUPPORTED;
3310     log::verbose("feature not supported");
3311   }
3312   return (bt_status_t)status;
3313 }
3314 
3315 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
3316         sizeof(bt_rc_ctrl_interface),
3317         init_ctrl,
3318         send_passthrough_cmd,
3319         send_groupnavigation_cmd,
3320         change_player_app_setting,
3321         play_item_cmd,
3322         get_current_metadata_cmd,
3323         get_playback_state_cmd,
3324         get_now_playing_list_cmd,
3325         get_folder_list_cmd,
3326         get_player_list_cmd,
3327         change_folder_path_cmd,
3328         set_browsed_player_cmd,
3329         set_addressed_player_cmd,
3330         set_volume_rsp,
3331         volume_change_notification_rsp,
3332         cleanup_ctrl,
3333 };
3334 
3335 /*******************************************************************************
3336  *
3337  * Function         btif_rc_ctrl_get_interface
3338  *
3339  * Description      Get the AVRCP Controller callback interface
3340  *
3341  * Returns          btrc_ctrl_interface_t
3342  *
3343  ******************************************************************************/
btif_rc_ctrl_get_interface(void)3344 const btrc_ctrl_interface_t* btif_rc_ctrl_get_interface(void) { return &bt_rc_ctrl_interface; }
3345 
3346 /*******************************************************************************
3347  *      Function         initialize_transaction
3348  *
3349  *      Description    Initializes fields of the transaction structure
3350  *
3351  *      Returns          void
3352  ******************************************************************************/
initialize_transaction(btif_rc_device_cb_t * p_dev,uint8_t lbl)3353 static void initialize_transaction(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3354   if (p_dev == nullptr) {
3355     return;
3356   }
3357   rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3358   std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3359   if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
3360     log::verbose("initialize transaction, dev={}, label={}", p_dev->rc_addr, lbl);
3361     if (alarm_is_scheduled(transaction_set->transaction[lbl].timer)) {
3362       log::warn("clearing pending timer event, dev={}, label={}", p_dev->rc_addr, lbl);
3363       clear_cmd_timeout(p_dev, lbl);
3364     }
3365     transaction_set->transaction[lbl] = {
3366             .in_use = false,
3367             .label = lbl,
3368             .context =
3369                     {
3370                             .rc_addr = RawAddress::kEmpty,
3371                             .label = MAX_LABEL,
3372                             .opcode = AVRC_OP_INVALID,
3373                             .command = {},
3374                     },
3375             .timer = nullptr,
3376     };
3377   }
3378 }
3379 
3380 /*******************************************************************************
3381  *
3382  * Function         init_all_transactions
3383  *
3384  * Description    Initializes all transactions
3385  *
3386  * Returns          void
3387  ******************************************************************************/
init_all_transactions(btif_rc_device_cb_t * p_dev)3388 void init_all_transactions(btif_rc_device_cb_t* p_dev) {
3389   if (p_dev == nullptr) {
3390     return;
3391   }
3392   for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; ++i) {
3393     initialize_transaction(p_dev, i);
3394   }
3395 }
3396 
3397 /*******************************************************************************
3398  *
3399  * Function         get_transaction_by_lbl
3400  *
3401  * Description    Will return a transaction based on the label. If not inuse
3402  *                     will return an error.
3403  *
3404  * Returns          bt_status_t
3405  ******************************************************************************/
get_transaction_by_lbl(btif_rc_device_cb_t * p_dev,uint8_t lbl)3406 rc_transaction_t* get_transaction_by_lbl(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3407   if (p_dev == nullptr) {
3408     return nullptr;
3409   }
3410 
3411   rc_transaction_t* transaction = NULL;
3412   rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3413   std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3414 
3415   /* Determine if this is a valid label */
3416   if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
3417     if (!transaction_set->transaction[lbl].in_use) {
3418       transaction = NULL;
3419     } else {
3420       transaction = &(transaction_set->transaction[lbl]);
3421     }
3422   }
3423   return transaction;
3424 }
3425 
3426 /*******************************************************************************
3427  *
3428  * Function         get_transaction
3429  *
3430  * Description    Obtains the transaction details.
3431  *
3432  * Returns          bt_status_t
3433  ******************************************************************************/
get_transaction(btif_rc_device_cb_t * p_dev,rc_transaction_context_t & context,rc_transaction_t ** ptransaction)3434 static bt_status_t get_transaction(btif_rc_device_cb_t* p_dev, rc_transaction_context_t& context,
3435                                    rc_transaction_t** ptransaction) {
3436   if (p_dev == NULL) {
3437     return BT_STATUS_PARM_INVALID;
3438   }
3439   rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3440   std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3441 
3442   // Check for unused transactions in the device's transaction set
3443   for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; i++) {
3444     if (!transaction_set->transaction[i].in_use) {
3445       context.label = i;
3446       transaction_set->transaction[i].context = context;
3447       transaction_set->transaction[i].in_use = true;
3448       *ptransaction = &(transaction_set->transaction[i]);
3449       log::verbose("Assigned transaction, dev={}, transaction={}", p_dev->rc_addr,
3450                    dump_transaction(*ptransaction));
3451       return BT_STATUS_SUCCESS;
3452     }
3453   }
3454   log::error("p_dev={}, failed to find free transaction", p_dev->rc_addr);
3455   return BT_STATUS_NOMEM;
3456 }
3457 
3458 /*******************************************************************************
3459  *
3460  * Function       start_transaction_timer
3461  *
3462  * Description    Starts a timer to release the label in case we don't get a
3463  *                response. Uses the central timeout handler, which will route
3464  *                timeout events based on context opcode and pdu_id
3465  *
3466  * Returns        void
3467  ******************************************************************************/
start_transaction_timer(btif_rc_device_cb_t * p_dev,uint8_t label,uint64_t timeout_ms)3468 static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label,
3469                                     uint64_t timeout_ms) {
3470   rc_transaction_t* transaction = get_transaction_by_lbl(p_dev, label);
3471   if (transaction == nullptr) {
3472     log::error("transaction is null");
3473     return;
3474   }
3475 
3476   if (alarm_is_scheduled(transaction->timer)) {
3477     log::warn("Restarting timer that's already scheduled");
3478   }
3479 
3480   std::stringstream ss;
3481   ss << "btif_rc." << p_dev->rc_addr.ToColonSepHexString() << "." << transaction->label;
3482   alarm_free(transaction->timer);
3483   transaction->timer = alarm_new(ss.str().c_str());
3484   alarm_set_on_mloop(transaction->timer, timeout_ms, btif_rc_transaction_timer_timeout,
3485                      &transaction->context);
3486 }
3487 
3488 /*******************************************************************************
3489  *
3490  * Function         release_transaction
3491  *
3492  * Description    Will release a transaction for reuse
3493  *
3494  * Returns          bt_status_t
3495  ******************************************************************************/
release_transaction(btif_rc_device_cb_t * p_dev,uint8_t lbl)3496 void release_transaction(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3497   if (p_dev == nullptr) {
3498     log::warn("Failed to release transaction, dev=null, label={}", lbl);
3499     return;
3500   }
3501   rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3502   std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3503 
3504   rc_transaction_t* transaction = get_transaction_by_lbl(p_dev, lbl);
3505 
3506   /* If the transaction is in use... */
3507   if (transaction != NULL) {
3508     log::verbose("Released transaction, dev={}, label={}", p_dev->rc_addr, lbl);
3509     initialize_transaction(p_dev, lbl);
3510   } else {
3511     log::warn("Failed to release transaction, could not find dev={}, label={}", p_dev->rc_addr,
3512               lbl);
3513   }
3514 }
3515 
3516 /*******************************************************************************
3517  *
3518  * Function       dump_transaction
3519  *
3520  * Description    Dump transactions info for debugging
3521  *
3522  * Returns        String of transaction info
3523  ******************************************************************************/
dump_transaction(const rc_transaction_t * const transaction)3524 static std::string dump_transaction(const rc_transaction_t* const transaction) {
3525   std::stringstream ss;
3526 
3527   ss << "label=" << (int)transaction->label;
3528   ss << " in_use=" << (transaction->in_use ? "true" : "false");
3529 
3530   rc_transaction_context_t context = transaction->context;
3531   ss << " context=(";
3532   uint8_t opcode_id = context.opcode;
3533   ss << "opcode=" << dump_rc_opcode(opcode_id);
3534   switch (opcode_id) {
3535     case AVRC_OP_VENDOR:
3536       ss << " pdu_id=" << dump_rc_pdu(context.command.vendor.pdu_id);
3537       if (context.command.vendor.pdu_id == AVRC_PDU_REGISTER_NOTIFICATION) {
3538         ss << " event_id=" << dump_rc_notification_event_id(context.command.vendor.event_id);
3539       }
3540       break;
3541     case AVRC_OP_BROWSE:
3542       ss << " pdu_id=" << dump_rc_pdu(context.command.browse.pdu_id);
3543       break;
3544     case AVRC_OP_PASS_THRU:
3545       ss << " rc_id=" << context.command.passthru.rc_id;
3546       ss << " key_state=" << context.command.passthru.key_state;
3547       break;
3548   }
3549   ss << ")";
3550 
3551   ss << " alarm=";
3552   alarm_t* alarm = transaction->timer;
3553   if (alarm != nullptr) {
3554     ss << "(set=" << alarm_is_scheduled(alarm) << " left=" << alarm_get_remaining_ms(alarm) << ")";
3555   } else {
3556     ss << "null";
3557   }
3558   return ss.str();
3559 }
3560 
3561 /***************************************************************************
3562  *
3563  * Function         vendor_cmd_timeout_handler
3564  *
3565  * Description      vendor dependent command timeout handler
3566  * Returns          None
3567  *
3568  **************************************************************************/
vendor_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_vendor_context_t * p_context)3569 static void vendor_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3570                                        rc_vendor_context_t* p_context) {
3571   if (p_dev == NULL) {
3572     log::error("p_dev NULL");
3573     return;
3574   }
3575 
3576   tAVRC_RESPONSE avrc_response = {0};
3577   tBTA_AV_META_MSG meta_msg = {.rc_handle = p_dev->rc_handle};
3578 
3579   log::warn("timeout, addr={}, label={}, pdu_id={}, event_id={}", p_dev->rc_addr, label,
3580             dump_rc_pdu(p_context->pdu_id), dump_rc_notification_event_id(p_context->event_id));
3581 
3582   switch (p_context->pdu_id) {
3583     case AVRC_PDU_REGISTER_NOTIFICATION:
3584       rc_notification_interim_timeout(p_dev, p_context->event_id);
3585       break;
3586 
3587     case AVRC_PDU_GET_CAPABILITIES:
3588       avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
3589       handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
3590       break;
3591 
3592     case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3593       avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
3594       handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
3595       break;
3596 
3597     case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3598       avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
3599       handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
3600       break;
3601 
3602     case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3603       avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
3604       handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
3605       break;
3606 
3607     case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3608       avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
3609       handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
3610       break;
3611 
3612     case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3613       avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
3614       handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
3615       break;
3616 
3617     case AVRC_PDU_GET_ELEMENT_ATTR:
3618       avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT;
3619       handle_get_metadata_attr_response(&meta_msg, &avrc_response.get_attrs);
3620       break;
3621 
3622     case AVRC_PDU_GET_PLAY_STATUS:
3623       avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT;
3624       handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status);
3625       break;
3626 
3627     case AVRC_PDU_SET_PLAYER_APP_VALUE:
3628       avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
3629       handle_set_app_attr_val_response(&meta_msg, &avrc_response.set_app_val);
3630       break;
3631 
3632     case AVRC_PDU_PLAY_ITEM:
3633       // Nothing to notify on, just release the label
3634       break;
3635 
3636     default:
3637       log::warn("timeout for unknown pdu_id={}", p_context->pdu_id);
3638       break;
3639   }
3640 }
3641 
3642 /***************************************************************************
3643  *
3644  * Function         browse_cmd_timeout_handler
3645  *
3646  * Description      Browse command timeout handler
3647  * Returns          None
3648  *
3649  **************************************************************************/
browse_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_browse_context_t * p_context)3650 static void browse_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3651                                        rc_browse_context_t* p_context) {
3652   if (p_dev == NULL) {
3653     log::error("p_dev NULL");
3654     return;
3655   }
3656 
3657   tAVRC_RESPONSE avrc_response = {0};
3658   tBTA_AV_META_MSG meta_msg = {
3659           .rc_handle = p_dev->rc_handle,
3660           .len = 0,
3661           .label = 0,
3662           .code = 0,
3663           .company_id = 0,
3664           .p_data = nullptr,
3665           .p_msg = nullptr,
3666   };
3667 
3668   log::warn("timeout, addr={}, label={}, pdu_id={}", p_dev->rc_addr, label,
3669             dump_rc_pdu(p_context->pdu_id));
3670 
3671   switch (p_context->pdu_id) {
3672     case AVRC_PDU_GET_FOLDER_ITEMS:
3673       avrc_response.get_items.status = BTIF_RC_STS_TIMEOUT;
3674       handle_get_folder_items_response(&meta_msg, &avrc_response.get_items);
3675       break;
3676     case AVRC_PDU_CHANGE_PATH:
3677       avrc_response.chg_path.status = BTIF_RC_STS_TIMEOUT;
3678       handle_change_path_response(&meta_msg, &avrc_response.chg_path);
3679       break;
3680     case AVRC_PDU_SET_BROWSED_PLAYER:
3681       avrc_response.br_player.status = BTIF_RC_STS_TIMEOUT;
3682       handle_set_browsed_player_response(&meta_msg, &avrc_response.br_player);
3683       break;
3684     case AVRC_PDU_GET_ITEM_ATTRIBUTES:
3685       avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT;
3686       handle_get_metadata_attr_response(&meta_msg, &avrc_response.get_attrs);
3687       break;
3688     default:
3689       log::warn("timeout for unknown pdu_id={}", p_context->pdu_id);
3690       break;
3691   }
3692 }
3693 
3694 /***************************************************************************
3695  *
3696  * Function         passthru_cmd_timeout_handler
3697  *
3698  * Description      Pass-thru command timeout handler
3699  * Returns          None
3700  *
3701  **************************************************************************/
passthru_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_passthru_context_t * p_context)3702 static void passthru_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3703                                          rc_passthru_context_t* p_context) {
3704   if (p_dev == NULL) {
3705     log::error("p_dev NULL");
3706     return;
3707   }
3708 
3709   log::warn("timeout, addr={}, label={}, rc_id={}, key_state={}", p_dev->rc_addr, label,
3710             p_context->rc_id, p_context->key_state);
3711 
3712   // Other requests are wrapped in a tAVRC_RESPONSE response object, but these
3713   // passthru events are not in there. As well, the upper layers don't handle
3714   // these events anyways. If that were to change, we could check the rc_id and
3715   // choose to route either the passthrough handler or vendorunique handler here
3716   return;
3717 }
3718 
3719 /***************************************************************************
3720  *
3721  * Function         btif_rc_transaction_timeout_handler
3722  *
3723  * Description      RC transaction timeout handler (Runs in BTIF context).
3724  * Returns          None
3725  *
3726  **************************************************************************/
btif_rc_transaction_timeout_handler(uint16_t,char * data)3727 static void btif_rc_transaction_timeout_handler(uint16_t /* event */, char* data) {
3728   rc_transaction_context_t* p_context = (rc_transaction_context_t*)data;
3729   if (p_context == nullptr) {
3730     log::error("p_context is null");
3731     return;
3732   }
3733 
3734   btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(p_context->rc_addr);
3735   if (p_dev == NULL) {
3736     log::error("p_dev is null");
3737     return;
3738   }
3739 
3740   uint8_t label = p_context->label;
3741   switch (p_context->opcode) {
3742     case AVRC_OP_VENDOR:
3743       vendor_cmd_timeout_handler(p_dev, label, &(p_context->command.vendor));
3744       break;
3745     case AVRC_OP_BROWSE:
3746       browse_cmd_timeout_handler(p_dev, label, &(p_context->command.browse));
3747       break;
3748     case AVRC_OP_PASS_THRU:
3749       passthru_cmd_timeout_handler(p_dev, label, &(p_context->command.passthru));
3750       break;
3751     default:
3752       log::warn("received timeout for unknown opcode={}", p_context->opcode);
3753       return;
3754   }
3755   release_transaction(p_dev, label);
3756 }
3757 
3758 /***************************************************************************
3759  *
3760  * Function         btif_rc_transaction_timer_timeout
3761  *
3762  * Description      RC transaction timeout callback.
3763  *                  This is called from BTU context and switches to BTIF
3764  *                  context to handle the timeout events
3765  * Returns          None
3766  *
3767  **************************************************************************/
btif_rc_transaction_timer_timeout(void * data)3768 static void btif_rc_transaction_timer_timeout(void* data) {
3769   rc_transaction_context_t* p_data = (rc_transaction_context_t*)data;
3770 
3771   btif_transfer_context(btif_rc_transaction_timeout_handler, 0, (char*)p_data,
3772                         sizeof(rc_transaction_context_t), NULL);
3773 }
3774 
3775 /*******************************************************************************
3776  *      Function       btif_debug_rc_dump
3777  *
3778  *      Description    Dumps the state of the btif_rc subsytem
3779  *
3780  *      Returns        void
3781  ******************************************************************************/
btif_debug_rc_dump(int fd)3782 void btif_debug_rc_dump(int fd) {
3783   dprintf(fd, "\nAVRCP Native State:\n");
3784 
3785   int connected_count = 0;
3786   for (int i = 0; i < BTIF_RC_NUM_CONN; ++i) {
3787     const btrc_connection_state_t state = btif_rc_cb.rc_multi_cb[i].rc_state;
3788     if (state != BTRC_CONNECTION_STATE_DISCONNECTED) {
3789       ++connected_count;
3790     }
3791   }
3792 
3793   dprintf(fd, "  Devices (%d / %d):\n", connected_count, BTIF_RC_NUM_CONN - 1);
3794   for (int i = 0; i < BTIF_RC_NUM_CONN; ++i) {
3795     btif_rc_device_cb_t* p_dev = &btif_rc_cb.rc_multi_cb[i];
3796     if (p_dev->rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) {
3797       dprintf(fd, "    %s:\n", p_dev->rc_addr.ToRedactedStringForLogging().c_str());
3798 
3799       rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3800       std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3801       dprintf(fd, "      Transaction Labels:\n");
3802       for (auto j = 0; j < MAX_TRANSACTIONS_PER_SESSION; ++j) {
3803         dprintf(fd, "        %s\n", dump_transaction(&transaction_set->transaction[j]).c_str());
3804       }
3805     }
3806   }
3807 }
3808