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