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