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