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