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