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