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 <base/functional/bind.h>
30 #include <bluetooth/log.h>
31 #include <hardware/bluetooth.h>
32 #include <hardware/bt_rc.h>
33 #include <stdio.h>
34 #include <string.h>
35 #include <time.h>
36
37 #include <cstdint>
38 #include <cstdio>
39 #include <mutex>
40 #include <sstream>
41 #include <string>
42
43 #include "bta/include/bta_av_api.h"
44 #include "btif/avrcp/avrcp_service.h"
45 #include "btif_av.h"
46 #include "btif_common.h"
47 #include "btif_util.h"
48 #include "device/include/interop.h"
49 #include "osi/include/alarm.h"
50 #include "osi/include/allocator.h"
51 #include "osi/include/list.h"
52 #include "osi/include/osi.h"
53 #include "osi/include/properties.h"
54 #include "stack/include/avrc_api.h"
55 #include "stack/include/avrc_defs.h"
56 #include "stack/include/bt_hdr.h"
57 #include "stack/include/bt_types.h"
58 #include "types/raw_address.h"
59
60 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
61
62 /*****************************************************************************
63 * Constants & Macros
64 *****************************************************************************/
65
66 /* cod value for Headsets */
67 #define COD_AV_HEADSETS 0x0404
68 /* for AVRC 1.4 need to change this */
69 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
70
71 #define IDX_GET_PLAY_STATUS_RSP 0
72 #define IDX_LIST_APP_ATTR_RSP 1
73 #define IDX_LIST_APP_VALUE_RSP 2
74 #define IDX_GET_CURR_APP_VAL_RSP 3
75 #define IDX_SET_APP_VAL_RSP 4
76 #define IDX_GET_APP_ATTR_TXT_RSP 5
77 #define IDX_GET_APP_VAL_TXT_RSP 6
78 #define IDX_GET_ELEMENT_ATTR_RSP 7
79 #define IDX_SET_ADDR_PLAYER_RSP 8
80 #define IDX_SET_BROWSED_PLAYER_RSP 9
81 #define IDX_GET_FOLDER_ITEMS_RSP 10
82 #define IDX_CHG_PATH_RSP 11
83 #define IDX_GET_ITEM_ATTR_RSP 12
84 #define IDX_PLAY_ITEM_RSP 13
85 #define IDX_GET_TOTAL_NUM_OF_ITEMS_RSP 14
86 #define IDX_SEARCH_RSP 15
87 #define IDX_ADD_TO_NOW_PLAYING_RSP 16
88
89 /* Update MAX value whenever IDX will be changed */
90 #define MAX_CMD_QUEUE_LEN 17
91
92 #define MAX_VOLUME 128
93 #define MAX_LABEL 16
94 #define MAX_TRANSACTIONS_PER_SESSION 16
95 #define PLAY_STATUS_PLAYING 1
96 #define BTIF_RC_NUM_CONN BT_RC_NUM_APP
97
98 #define CHECK_RC_CONNECTED(p_dev) \
99 do { \
100 if ((p_dev) == NULL || !(p_dev)->rc_connected) { \
101 log::warn("called when RC is not connected"); \
102 return BT_STATUS_NOT_READY; \
103 } \
104 } while (0)
105
106 #define CHECK_BR_CONNECTED(p_dev) \
107 do { \
108 if ((p_dev) == NULL || !(p_dev)->br_connected) { \
109 log::warn("called when BR is not connected"); \
110 return BT_STATUS_NOT_READY; \
111 } \
112 } while (0)
113
114 using namespace bluetooth;
115
116 /*****************************************************************************
117 * Local type definitions
118 *****************************************************************************/
119 typedef struct {
120 uint8_t bNotify;
121 uint8_t label;
122 } btif_rc_reg_notifications_t;
123
124 typedef struct {
125 uint8_t label;
126 uint8_t ctype;
127 bool is_rsp_pending;
128 } btif_rc_cmd_ctxt_t;
129
130 /* 2 second timeout to get command response, then we free label */
131 #define BTIF_RC_TIMEOUT_MS (2 * 1000)
132
133 typedef enum { eNOT_REGISTERED, eREGISTERED, eINTERIM } btif_rc_nfn_reg_status_t;
134
135 typedef struct {
136 uint8_t event_id;
137 uint8_t label;
138 btif_rc_nfn_reg_status_t status;
139 } btif_rc_supported_event_t;
140
141 #define BTIF_RC_STS_TIMEOUT 0xFE
142
143 typedef struct {
144 bool query_started;
145 uint8_t num_attrs;
146 uint8_t num_ext_attrs;
147
148 uint8_t attr_index;
149 uint8_t ext_attr_index;
150 uint8_t ext_val_index;
151 btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
152 btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
153 } btif_rc_player_app_settings_t;
154
155 // The context associated with a passthru command
156 typedef struct {
157 uint8_t rc_id;
158 uint8_t key_state;
159 uint8_t custom_id;
160 } rc_passthru_context_t;
161
162 // The context associated with a vendor command
163 typedef struct {
164 uint8_t pdu_id;
165 uint8_t event_id;
166 } rc_vendor_context_t;
167
168 // The context associated with a browsing command
169 typedef struct {
170 uint8_t pdu_id;
171 } rc_browse_context_t;
172
173 typedef union {
174 rc_vendor_context_t vendor;
175 rc_browse_context_t browse;
176 rc_passthru_context_t passthru;
177 } rc_command_context_t;
178
179 // The context associated with any command transaction requiring a label.
180 // The opcode determines how to determine the data in the union. Context is
181 // used to track which requests have which labels
182 typedef struct {
183 RawAddress rc_addr;
184 uint8_t label;
185 uint8_t opcode;
186 rc_command_context_t command;
187 } rc_transaction_context_t;
188 typedef struct {
189 bool in_use;
190 uint8_t label;
191 rc_transaction_context_t context;
192 alarm_t* timer;
193 } rc_transaction_t;
194
195 typedef struct {
196 std::recursive_mutex label_lock;
197 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
198 } rc_transaction_set_t;
199
200 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single
201 * struct */
202 typedef struct {
203 bool rc_connected;
204 bool br_connected; // Browsing channel.
205 uint8_t rc_handle;
206 tBTA_AV_FEAT rc_features;
207 uint16_t rc_cover_art_psm; // AVRCP-BIP psm
208 btrc_connection_state_t rc_state;
209 RawAddress rc_addr;
210 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
211 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
212 unsigned int rc_volume;
213 uint8_t rc_vol_label;
214 list_t* rc_supported_event_list;
215 btif_rc_player_app_settings_t rc_app_settings;
216 alarm_t* rc_play_status_timer;
217 bool rc_features_processed;
218 uint64_t rc_playing_uid;
219 bool rc_procedure_complete;
220 rc_transaction_set_t transaction_set;
221 tBTA_AV_FEAT peer_ct_features;
222 tBTA_AV_FEAT peer_tg_features;
223 uint8_t launch_cmd_pending; /* true: getcap/regvolume */
224 } btif_rc_device_cb_t;
225
226 #define RC_PENDING_ACT_GET_CAP (1 << 0)
227 #define RC_PENDING_ACT_REG_VOL (1 << 1)
228 #define RC_PENDING_ACT_REPORT_CONN (1 << 2)
229
230 typedef struct {
231 std::mutex lock;
232 btif_rc_device_cb_t rc_multi_cb[BTIF_RC_NUM_CONN];
233 } rc_cb_t;
234
235 typedef struct {
236 uint8_t handle;
237 } btif_rc_handle_t;
238
239 /* Response status code - Unknown Error - this is changed to "reserved" */
240 #define BTIF_STS_GEN_ERROR 0x06
241
242 /* Utility table to map hal status codes to bta status codes for the response
243 * status */
244 static const uint8_t status_code_map[] = {
245 /* BTA_Status codes HAL_Status codes */
246 AVRC_STS_BAD_CMD, /* BTRC_STS_BAD_CMD */
247 AVRC_STS_BAD_PARAM, /* BTRC_STS_BAD_PARAM */
248 AVRC_STS_NOT_FOUND, /* BTRC_STS_NOT_FOUND */
249 AVRC_STS_INTERNAL_ERR, /* BTRC_STS_INTERNAL_ERR */
250 AVRC_STS_NO_ERROR, /* BTRC_STS_NO_ERROR */
251 AVRC_STS_UID_CHANGED, /* BTRC_STS_UID_CHANGED */
252 BTIF_STS_GEN_ERROR, /* BTRC_STS_RESERVED */
253 AVRC_STS_BAD_DIR, /* BTRC_STS_INV_DIRN */
254 AVRC_STS_NOT_DIR, /* BTRC_STS_INV_DIRECTORY */
255 AVRC_STS_NOT_EXIST, /* BTRC_STS_INV_ITEM */
256 AVRC_STS_BAD_SCOPE, /* BTRC_STS_INV_SCOPE */
257 AVRC_STS_BAD_RANGE, /* BTRC_STS_INV_RANGE */
258 AVRC_STS_UID_IS_DIR, /* BTRC_STS_DIRECTORY */
259 AVRC_STS_IN_USE, /* BTRC_STS_MEDIA_IN_USE */
260 AVRC_STS_NOW_LIST_FULL, /* BTRC_STS_PLAY_LIST_FULL */
261 AVRC_STS_SEARCH_NOT_SUP, /* BTRC_STS_SRCH_NOT_SPRTD */
262 AVRC_STS_SEARCH_BUSY, /* BTRC_STS_SRCH_IN_PROG */
263 AVRC_STS_BAD_PLAYER_ID, /* BTRC_STS_INV_PLAYER */
264 AVRC_STS_PLAYER_N_BR, /* BTRC_STS_PLAY_NOT_BROW */
265 AVRC_STS_PLAYER_N_ADDR, /* BTRC_STS_PLAY_NOT_ADDR */
266 AVRC_STS_BAD_SEARCH_RES, /* BTRC_STS_INV_RESULTS */
267 AVRC_STS_NO_AVAL_PLAYER, /* BTRC_STS_NO_AVBL_PLAY */
268 AVRC_STS_ADDR_PLAYER_CHG, /* BTRC_STS_ADDR_PLAY_CHGD */
269 };
270
271 static void initialize_device(btif_rc_device_cb_t* p_dev);
272 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, uint8_t status,
273 uint8_t opcode);
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, rc_transaction_context_t& context,
276 rc_transaction_t** ptransaction);
277 static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label, uint64_t timeout_ms);
278 static void btif_rc_transaction_timer_timeout(void* data);
279 static void release_transaction(btif_rc_device_cb_t* p_dev, uint8_t label);
280 static std::string dump_transaction(const rc_transaction_t* const transaction);
281 static rc_transaction_t* get_transaction_by_lbl(btif_rc_device_cb_t* p_dev, uint8_t label);
282
283 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg);
284 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg);
285 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t label,
286 btif_rc_device_cb_t* p_dev);
287 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev);
288 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
289 btif_rc_device_cb_t* p_dev);
290 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_CAPS_RSP* p_rsp);
291 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_ATTR_RSP* p_rsp);
292 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_VALUES_RSP* p_rsp);
293 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
294 tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp);
295 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
296 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
297 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg,
298 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp);
299 static void cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t* p_app_settings);
300 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
301 tAVRC_GET_PLAY_STATUS_RSP* p_rsp);
302 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* p_rsp);
303 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, uint8_t item_count);
304 static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg,
305 tAVRC_GET_ATTRS_RSP* p_rsp);
306 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* p_rsp);
307 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev);
308 static bt_status_t get_player_app_setting_attr_text_cmd(uint8_t* attrs, uint8_t num_attrs,
309 btif_rc_device_cb_t* p_dev);
310 static bt_status_t get_player_app_setting_value_text_cmd(uint8_t* vals, uint8_t num_vals,
311 btif_rc_device_cb_t* p_dev);
312 static bt_status_t register_notification_cmd(uint8_t event_id, uint32_t event_value,
313 btif_rc_device_cb_t* p_dev);
314 static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
315 btif_rc_device_cb_t* p_dev);
316 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
317 btif_rc_device_cb_t* p_dev);
318 static bt_status_t get_item_attribute_cmd(uint64_t uid, int scope, uint8_t num_attribute,
319 const uint32_t* p_attr_ids, btif_rc_device_cb_t* p_dev);
320 static bt_status_t getcapabilities_cmd(uint8_t cap_id, btif_rc_device_cb_t* p_dev);
321 static bt_status_t list_player_app_setting_attrib_cmd(btif_rc_device_cb_t* p_dev);
322 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id, btif_rc_device_cb_t* p_dev);
323 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids,
324 btif_rc_device_cb_t* p_dev);
325 static void get_folder_item_type_media(const tAVRC_ITEM* avrc_item, btrc_folder_items_t* btrc_item);
326 static void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
327 btrc_folder_items_t* btrc_item);
328 static void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
329 btrc_folder_items_t* btrc_item);
330 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, uint8_t scope,
331 uint32_t start_item, uint32_t end_item);
332
333 /*****************************************************************************
334 * Static variables
335 *****************************************************************************/
336 static rc_cb_t btif_rc_cb;
337 static btrc_ctrl_callbacks_t* bt_rc_ctrl_callbacks = NULL;
338
339 // List of desired media attribute keys to request by default
340 static const uint32_t media_attr_list[] = {
341 AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST,
342 AVRC_MEDIA_ATTR_ID_ALBUM, AVRC_MEDIA_ATTR_ID_TRACK_NUM,
343 AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE,
344 AVRC_MEDIA_ATTR_ID_PLAYING_TIME, AVRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE};
345 static const uint8_t media_attr_list_size = sizeof(media_attr_list) / sizeof(uint32_t);
346
347 // List of desired media attribute keys to request if cover artwork is not a
348 // supported feature
349 static const uint32_t media_attr_list_no_cover_art[] = {
350 AVRC_MEDIA_ATTR_ID_TITLE, AVRC_MEDIA_ATTR_ID_ARTIST, AVRC_MEDIA_ATTR_ID_ALBUM,
351 AVRC_MEDIA_ATTR_ID_TRACK_NUM, AVRC_MEDIA_ATTR_ID_NUM_TRACKS, AVRC_MEDIA_ATTR_ID_GENRE,
352 AVRC_MEDIA_ATTR_ID_PLAYING_TIME};
353 static const uint8_t media_attr_list_no_cover_art_size =
354 sizeof(media_attr_list_no_cover_art) / sizeof(uint32_t);
355
356 /*****************************************************************************
357 * Static functions
358 *****************************************************************************/
359
360 /*****************************************************************************
361 * Externs
362 *****************************************************************************/
363
btif_rc_get_addr_by_handle(uint8_t handle,RawAddress & rc_addr)364 void btif_rc_get_addr_by_handle(uint8_t handle, RawAddress& rc_addr) {
365 log::verbose("handle: 0x{:x}", handle);
366 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
367 if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
368 (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) {
369 log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}",
370 btif_rc_cb.rc_multi_cb[idx].rc_handle);
371 rc_addr = btif_rc_cb.rc_multi_cb[idx].rc_addr;
372 return;
373 }
374 }
375 log::error("returning NULL");
376 rc_addr = RawAddress::kEmpty;
377 return;
378 }
379
380 /*****************************************************************************
381 * Functions
382 *****************************************************************************/
alloc_device()383 static btif_rc_device_cb_t* alloc_device() {
384 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
385 if (btif_rc_cb.rc_multi_cb[idx].rc_state == BTRC_CONNECTION_STATE_DISCONNECTED) {
386 return &btif_rc_cb.rc_multi_cb[idx];
387 }
388 }
389 return NULL;
390 }
391
initialize_device(btif_rc_device_cb_t * p_dev)392 static void initialize_device(btif_rc_device_cb_t* p_dev) {
393 if (p_dev == nullptr) {
394 return;
395 }
396
397 p_dev->rc_connected = false;
398 p_dev->br_connected = false;
399 p_dev->rc_handle = 0;
400 p_dev->rc_features = 0;
401 p_dev->rc_cover_art_psm = 0;
402 p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
403 p_dev->rc_addr = RawAddress::kEmpty;
404 for (int i = 0; i < MAX_CMD_QUEUE_LEN; ++i) {
405 p_dev->rc_pdu_info[i].ctype = 0;
406 p_dev->rc_pdu_info[i].label = 0;
407 p_dev->rc_pdu_info[i].is_rsp_pending = false;
408 }
409 if (p_dev->rc_supported_event_list != nullptr) {
410 list_clear(p_dev->rc_supported_event_list);
411 }
412 p_dev->rc_supported_event_list = nullptr;
413 p_dev->rc_volume = MAX_VOLUME;
414 p_dev->rc_vol_label = MAX_LABEL;
415 memset(&p_dev->rc_app_settings, 0, sizeof(btif_rc_player_app_settings_t));
416 p_dev->rc_play_status_timer = nullptr;
417 p_dev->rc_features_processed = false;
418 p_dev->rc_playing_uid = 0;
419 p_dev->rc_procedure_complete = false;
420 p_dev->peer_ct_features = 0;
421 p_dev->peer_tg_features = 0;
422 p_dev->launch_cmd_pending = 0;
423
424 // Reset the transaction set for this device. If this initialize_device() call
425 // is made due to a disconnect event, this cancels any pending timers too.
426 init_all_transactions(p_dev);
427 }
428
get_connected_device(int index)429 static btif_rc_device_cb_t* get_connected_device(int index) {
430 log::verbose("index: {}", index);
431 if (index >= BTIF_RC_NUM_CONN) {
432 log::error("can't support more than {} connections", BTIF_RC_NUM_CONN);
433 return NULL;
434 }
435 if (btif_rc_cb.rc_multi_cb[index].rc_state != BTRC_CONNECTION_STATE_CONNECTED) {
436 log::error("returning NULL");
437 return NULL;
438 }
439 return &btif_rc_cb.rc_multi_cb[index];
440 }
441
btif_rc_get_device_by_bda(const RawAddress & bd_addr)442 static btif_rc_device_cb_t* btif_rc_get_device_by_bda(const RawAddress& bd_addr) {
443 log::verbose("bd_addr: {}", bd_addr);
444
445 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
446 if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
447 btif_rc_cb.rc_multi_cb[idx].rc_addr == bd_addr) {
448 return &btif_rc_cb.rc_multi_cb[idx];
449 }
450 }
451 log::error("device not found, returning NULL!");
452 return NULL;
453 }
454
btif_rc_get_device_by_handle(uint8_t handle)455 static btif_rc_device_cb_t* btif_rc_get_device_by_handle(uint8_t handle) {
456 log::verbose("handle: 0x{:x}", handle);
457 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
458 if ((btif_rc_cb.rc_multi_cb[idx].rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) &&
459 (btif_rc_cb.rc_multi_cb[idx].rc_handle == handle)) {
460 log::verbose("btif_rc_cb.rc_multi_cb[idx].rc_handle: 0x{:x}",
461 btif_rc_cb.rc_multi_cb[idx].rc_handle);
462 return &btif_rc_cb.rc_multi_cb[idx];
463 }
464 }
465 log::error("returning NULL");
466 return NULL;
467 }
468
get_requested_attributes_list(btif_rc_device_cb_t * p_dev)469 static const uint32_t* get_requested_attributes_list(btif_rc_device_cb_t* p_dev) {
470 return p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK ? media_attr_list
471 : media_attr_list_no_cover_art;
472 }
473
get_requested_attributes_list_size(btif_rc_device_cb_t * p_dev)474 static uint8_t get_requested_attributes_list_size(btif_rc_device_cb_t* p_dev) {
475 return p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK ? media_attr_list_size
476 : media_attr_list_no_cover_art_size;
477 }
478
handle_rc_ctrl_features_all(btif_rc_device_cb_t * p_dev)479 static void handle_rc_ctrl_features_all(btif_rc_device_cb_t* p_dev) {
480 if (!(p_dev->peer_tg_features & BTA_AV_FEAT_RCTG) &&
481 (!(p_dev->peer_tg_features & BTA_AV_FEAT_RCCT) ||
482 !(p_dev->peer_tg_features & BTA_AV_FEAT_ADV_CTRL))) {
483 return;
484 }
485
486 int rc_features = 0;
487
488 log::verbose(
489 "peer_tg_features: 0x{:x}, rc_features_processed={}, connected={}, "
490 "peer_is_src:{}",
491 p_dev->peer_tg_features, p_dev->rc_features_processed,
492 btif_av_is_connected_addr(p_dev->rc_addr, A2dpType::kSink),
493 btif_av_peer_is_source(p_dev->rc_addr));
494
495 if ((p_dev->peer_tg_features & BTA_AV_FEAT_ADV_CTRL) &&
496 (p_dev->peer_tg_features & BTA_AV_FEAT_RCCT)) {
497 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
498 }
499
500 if ((p_dev->peer_tg_features & BTA_AV_FEAT_METADATA) &&
501 (p_dev->peer_tg_features & BTA_AV_FEAT_VENDOR) && (p_dev->rc_features_processed != true)) {
502 rc_features |= BTRC_FEAT_METADATA;
503
504 /* Mark rc features processed to avoid repeating
505 * the AVRCP procedure every time on receiving this
506 * update.
507 */
508 p_dev->rc_features_processed = true;
509 }
510
511 if (btif_av_is_connected_addr(p_dev->rc_addr, A2dpType::kSink)) {
512 if (btif_av_peer_is_source(p_dev->rc_addr)) {
513 p_dev->rc_features = p_dev->peer_tg_features;
514 if ((p_dev->peer_tg_features & BTA_AV_FEAT_METADATA) &&
515 (p_dev->peer_tg_features & BTA_AV_FEAT_VENDOR)) {
516 getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
517 }
518 }
519 } else {
520 log::verbose("{} is not connected, pending", p_dev->rc_addr);
521 p_dev->launch_cmd_pending |= (RC_PENDING_ACT_GET_CAP | RC_PENDING_ACT_REG_VOL);
522 }
523
524 /* Add browsing feature capability */
525 if (p_dev->peer_tg_features & BTA_AV_FEAT_BROWSE) {
526 rc_features |= BTRC_FEAT_BROWSE;
527 }
528
529 /* Add cover art feature capability */
530 if (p_dev->peer_tg_features & BTA_AV_FEAT_COVER_ARTWORK) {
531 rc_features |= BTRC_FEAT_COVER_ARTWORK;
532 }
533
534 if (bt_rc_ctrl_callbacks != NULL) {
535 log::verbose("Update rc features to CTRL: {}", rc_features);
536 do_in_jni_thread(
537 base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features));
538 }
539 }
540
handle_rc_ctrl_features(btif_rc_device_cb_t * p_dev)541 static void handle_rc_ctrl_features(btif_rc_device_cb_t* p_dev) {
542 if (btif_av_src_sink_coexist_enabled() && btif_av_both_enable()) {
543 handle_rc_ctrl_features_all(p_dev);
544 return;
545 }
546
547 if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG) &&
548 (!(p_dev->rc_features & BTA_AV_FEAT_RCCT) || !(p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL))) {
549 return;
550 }
551
552 int rc_features = 0;
553
554 if ((p_dev->rc_features & BTA_AV_FEAT_ADV_CTRL) && (p_dev->rc_features & BTA_AV_FEAT_RCCT)) {
555 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
556 }
557
558 if (p_dev->rc_features & BTA_AV_FEAT_METADATA) {
559 rc_features |= BTRC_FEAT_METADATA;
560 }
561
562 if ((p_dev->rc_features & BTA_AV_FEAT_VENDOR) && (p_dev->rc_features_processed != true)) {
563 /* Mark rc features processed to avoid repeating
564 * the AVRCP procedure every time on receiving this
565 * update.
566 */
567 p_dev->rc_features_processed = true;
568 if (btif_av_is_sink_enabled()) {
569 getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
570 }
571 }
572
573 /* Add browsing feature capability */
574 if (p_dev->rc_features & BTA_AV_FEAT_BROWSE) {
575 rc_features |= BTRC_FEAT_BROWSE;
576 }
577
578 /* Add cover art feature capability */
579 if (p_dev->rc_features & BTA_AV_FEAT_COVER_ARTWORK) {
580 rc_features |= BTRC_FEAT_COVER_ARTWORK;
581 }
582
583 log::verbose("Update rc features to CTRL: {}", rc_features);
584 do_in_jni_thread(
585 base::BindOnce(bt_rc_ctrl_callbacks->getrcfeatures_cb, p_dev->rc_addr, rc_features));
586 }
btif_rc_check_pending_cmd(const RawAddress & peer_address)587 void btif_rc_check_pending_cmd(const RawAddress& peer_address) {
588 btif_rc_device_cb_t* p_dev = NULL;
589 p_dev = btif_rc_get_device_by_bda(peer_address);
590 if (p_dev == NULL) {
591 log::error("p_dev NULL");
592 return;
593 }
594
595 log::verbose(
596 "launch_cmd_pending={}, rc_connected={}, peer_ct_features=0x{:x}, "
597 "peer_tg_features=0x{:x}",
598 p_dev->launch_cmd_pending, p_dev->rc_connected, p_dev->peer_ct_features,
599 p_dev->peer_tg_features);
600 if (p_dev->launch_cmd_pending && p_dev->rc_connected) {
601 if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REG_VOL) &&
602 btif_av_peer_is_sink(p_dev->rc_addr)) {
603 if (bluetooth::avrcp::AvrcpService::Get() != nullptr) {
604 bluetooth::avrcp::AvrcpService::Get()->RegisterVolChanged(peer_address);
605 }
606 }
607 if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_GET_CAP) &&
608 btif_av_peer_is_source(p_dev->rc_addr)) {
609 p_dev->rc_features = p_dev->peer_tg_features;
610 getcapabilities_cmd(AVRC_CAP_COMPANY_ID, p_dev);
611 }
612 if ((p_dev->launch_cmd_pending & RC_PENDING_ACT_REPORT_CONN) &&
613 btif_av_peer_is_source(p_dev->rc_addr)) {
614 if (bt_rc_ctrl_callbacks != NULL) {
615 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, false,
616 p_dev->rc_addr));
617 }
618 }
619 }
620 p_dev->launch_cmd_pending = 0;
621 }
622
handle_rc_ctrl_psm(btif_rc_device_cb_t * p_dev)623 static void handle_rc_ctrl_psm(btif_rc_device_cb_t* p_dev) {
624 uint16_t cover_art_psm = p_dev->rc_cover_art_psm;
625 log::verbose("Update rc cover art psm to CTRL: {}", cover_art_psm);
626 if (bt_rc_ctrl_callbacks != NULL) {
627 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_cover_art_psm_cb, p_dev->rc_addr,
628 cover_art_psm));
629 }
630 }
631
632 /***************************************************************************
633 * Function handle_rc_browse_connect
634 *
635 * - Argument: tBTA_AV_RC_OPEN browse RC open data structure
636 *
637 * - Description: browse RC connection event handler
638 *
639 ***************************************************************************/
handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN * p_rc_br_open)640 static void handle_rc_browse_connect(tBTA_AV_RC_BROWSE_OPEN* p_rc_br_open) {
641 log::verbose("rc_handle {} status {}", p_rc_br_open->rc_handle, p_rc_br_open->status);
642 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(p_rc_br_open->rc_handle);
643
644 if (!p_dev) {
645 log::error("p_dev is null");
646 return;
647 }
648
649 /* check that we are already connected to this address since being connected
650 * to a browse when not connected to the control channel over AVRCP is
651 * probably not preferred anyways. */
652 if (p_rc_br_open->status == BTA_AV_SUCCESS) {
653 p_dev->br_connected = true;
654 if (btif_av_src_sink_coexist_enabled()) {
655 if (btif_av_peer_is_connected_source(p_dev->rc_addr)) {
656 if (bt_rc_ctrl_callbacks != NULL) {
657 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, true,
658 p_dev->rc_addr));
659 }
660 } else {
661 p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN;
662 log::verbose("pending rc browse connection event");
663 }
664 } else {
665 if (bt_rc_ctrl_callbacks != NULL) {
666 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, true,
667 p_dev->rc_addr));
668 } else {
669 log::warn("bt_rc_ctrl_callbacks is null.");
670 }
671 }
672 }
673 }
674
675 /***************************************************************************
676 * Function handle_rc_connect
677 *
678 * - Argument: tBTA_AV_RC_OPEN RC open data structure
679 *
680 * - Description: RC connection event handler
681 *
682 ***************************************************************************/
handle_rc_connect(tBTA_AV_RC_OPEN * p_rc_open)683 static void handle_rc_connect(tBTA_AV_RC_OPEN* p_rc_open) {
684 log::verbose("rc_handle: {}", p_rc_open->rc_handle);
685
686 btif_rc_device_cb_t* p_dev = alloc_device();
687 if (p_dev == NULL) {
688 log::error("p_dev is NULL");
689 return;
690 }
691
692 if (!(p_rc_open->status == BTA_AV_SUCCESS)) {
693 log::error("Connect failed with error code: {}", p_rc_open->status);
694 p_dev->rc_connected = false;
695 BTA_AvCloseRc(p_rc_open->rc_handle);
696 p_dev->rc_handle = 0;
697 p_dev->rc_state = BTRC_CONNECTION_STATE_DISCONNECTED;
698 p_dev->rc_features = 0;
699 p_dev->peer_ct_features = 0;
700 p_dev->peer_tg_features = 0;
701 p_dev->launch_cmd_pending = 0;
702 p_dev->rc_vol_label = MAX_LABEL;
703 p_dev->rc_volume = MAX_VOLUME;
704 p_dev->rc_addr = RawAddress::kEmpty;
705 return;
706 }
707
708 // check if already some RC is connected
709 if (p_dev->rc_connected) {
710 log::error("Got RC OPEN in connected state, Connected RC: {} and Current RC: {}",
711 p_dev->rc_handle, p_rc_open->rc_handle);
712 if (p_dev->rc_handle != p_rc_open->rc_handle && p_dev->rc_addr != p_rc_open->peer_addr) {
713 log::verbose("Got RC connected for some other handle");
714 BTA_AvCloseRc(p_rc_open->rc_handle);
715 return;
716 }
717 }
718 p_dev->rc_addr = p_rc_open->peer_addr;
719 p_dev->rc_features = p_rc_open->peer_features;
720 p_dev->peer_ct_features = p_rc_open->peer_ct_features;
721 p_dev->peer_tg_features = p_rc_open->peer_tg_features;
722 p_dev->rc_cover_art_psm = p_rc_open->cover_art_psm;
723 p_dev->rc_vol_label = MAX_LABEL;
724 p_dev->rc_volume = MAX_VOLUME;
725
726 log::verbose(
727 "handle_rc_connect in features={:#x}, out features={:#x}, "
728 "ct_feature={:#x}, tg_feature={:#x}, cover art psm={:#x}",
729 p_rc_open->peer_features, p_dev->rc_features, p_dev->peer_ct_features,
730 p_dev->peer_tg_features, p_dev->rc_cover_art_psm);
731
732 p_dev->rc_connected = true;
733 p_dev->rc_handle = p_rc_open->rc_handle;
734 p_dev->rc_state = BTRC_CONNECTION_STATE_CONNECTED;
735
736 p_dev->rc_playing_uid = RC_INVALID_TRACK_ID;
737
738 if (btif_av_src_sink_coexist_enabled() && !btif_av_peer_is_connected_source(p_dev->rc_addr)) {
739 p_dev->launch_cmd_pending |= RC_PENDING_ACT_REPORT_CONN;
740 log::verbose("pending rc connection event");
741 return;
742 }
743 if (bt_rc_ctrl_callbacks != NULL) {
744 do_in_jni_thread(
745 base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, true, false, p_dev->rc_addr));
746 /* report connection state if remote device is AVRCP target */
747 handle_rc_ctrl_features(p_dev);
748
749 /* report psm if remote device is AVRCP target */
750 handle_rc_ctrl_psm(p_dev);
751 }
752 }
753
754 /***************************************************************************
755 * Function handle_rc_disconnect
756 *
757 * - Argument: tBTA_AV_RC_CLOSE RC close data structure
758 *
759 * - Description: RC disconnection event handler
760 *
761 ***************************************************************************/
handle_rc_disconnect(tBTA_AV_RC_CLOSE * p_rc_close)762 static void handle_rc_disconnect(tBTA_AV_RC_CLOSE* p_rc_close) {
763 btif_rc_device_cb_t* p_dev = NULL;
764 log::verbose("rc_handle: {}", p_rc_close->rc_handle);
765
766 p_dev = btif_rc_get_device_by_handle(p_rc_close->rc_handle);
767 if (p_dev == NULL) {
768 log::error("Got disconnect from invalid rc handle");
769 return;
770 }
771
772 if (p_rc_close->rc_handle != p_dev->rc_handle && p_dev->rc_addr != p_rc_close->peer_addr) {
773 log::error("Got disconnect of unknown device");
774 return;
775 }
776
777 /* Report connection state if device is AVRCP target */
778 if (bt_rc_ctrl_callbacks != NULL) {
779 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->connection_state_cb, false, false,
780 p_dev->rc_addr));
781 }
782
783 // We'll re-initialize the device state back to what it looked like before
784 // the connection. This will free ongoing transaction labels and clear any
785 // running label timers
786 initialize_device(p_dev);
787 }
788
789 /***************************************************************************
790 * Function handle_rc_passthrough_rsp
791 *
792 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response
793 *
794 * - Description: Remote control passthrough response handler
795 *
796 ***************************************************************************/
handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)797 static void handle_rc_passthrough_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
798 btif_rc_device_cb_t* p_dev = NULL;
799
800 p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
801 if (p_dev == NULL) {
802 log::error("passthrough response for Invalid rc handle");
803 return;
804 }
805
806 if (!(p_dev->rc_features & BTA_AV_FEAT_RCTG)) {
807 log::error("DUT does not support AVRCP controller role");
808 return;
809 }
810
811 const char* status = (p_remote_rsp->key_state == 1) ? "released" : "pressed";
812 log::verbose("rc_id: {} state: {}", p_remote_rsp->rc_id, status);
813
814 release_transaction(p_dev, p_remote_rsp->label);
815 if (bt_rc_ctrl_callbacks != NULL) {
816 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->passthrough_rsp_cb, p_dev->rc_addr,
817 p_remote_rsp->rc_id, p_remote_rsp->key_state));
818 }
819 }
820
821 /***************************************************************************
822 * Function handle_rc_vendorunique_rsp
823 *
824 * - Argument: tBTA_AV_REMOTE_RSP command response
825 *
826 * - Description: Remote control vendor unique response handler
827 *
828 ***************************************************************************/
handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP * p_remote_rsp)829 static void handle_rc_vendorunique_rsp(tBTA_AV_REMOTE_RSP* p_remote_rsp) {
830 btif_rc_device_cb_t* p_dev = NULL;
831 const char* status;
832 uint8_t vendor_id = 0;
833
834 p_dev = btif_rc_get_device_by_handle(p_remote_rsp->rc_handle);
835 if (p_dev == NULL) {
836 log::error("Got vendorunique rsp from invalid rc handle");
837 return;
838 }
839
840 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
841 int key_state;
842 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE) {
843 status = "released";
844 key_state = 1;
845 } else {
846 status = "pressed";
847 key_state = 0;
848 }
849
850 if (p_remote_rsp->len > 0 && p_remote_rsp->p_data != NULL) {
851 if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN) {
852 vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN - 1];
853 }
854 osi_free_and_reset((void**)&p_remote_rsp->p_data);
855 }
856 log::verbose("vendor_id: {} status: {}", vendor_id, status);
857
858 release_transaction(p_dev, p_remote_rsp->label);
859 do_in_jni_thread(
860 base::BindOnce(bt_rc_ctrl_callbacks->groupnavigation_rsp_cb, vendor_id, key_state));
861 } else {
862 log::error("Remote does not support AVRCP TG role");
863 }
864 }
865
866 /***************************************************************************
867 **
868 ** Function btif_rc_handler
869 **
870 ** Description RC event handler
871 **
872 ***************************************************************************/
btif_rc_handler(tBTA_AV_EVT event,tBTA_AV * p_data)873 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV* p_data) {
874 log::verbose("event: {}", dump_rc_event(event));
875 btif_rc_device_cb_t* p_dev = NULL;
876 switch (event) {
877 case BTA_AV_RC_OPEN_EVT: {
878 log::verbose("Peer_features: 0x{:x} Cover Art PSM: 0x{:x}", p_data->rc_open.peer_features,
879 p_data->rc_open.cover_art_psm);
880 handle_rc_connect(&(p_data->rc_open));
881 } break;
882
883 case BTA_AV_RC_BROWSE_OPEN_EVT: {
884 /* tell the UL that we have connection to browse channel and that
885 * browse commands can be directed accordingly. */
886 handle_rc_browse_connect(&p_data->rc_browse_open);
887 } break;
888
889 case BTA_AV_RC_CLOSE_EVT: {
890 handle_rc_disconnect(&(p_data->rc_close));
891 } break;
892
893 case BTA_AV_RC_BROWSE_CLOSE_EVT: {
894 log::verbose("BTA_AV_RC_BROWSE_CLOSE_EVT");
895 } break;
896
897 case BTA_AV_REMOTE_CMD_EVT: {
898 log::error("AVRCP TG role not up, drop passthrough commands");
899 } break;
900
901 case BTA_AV_REMOTE_RSP_EVT: {
902 log::verbose("RSP: rc_id: 0x{:x} key_state: {}", p_data->remote_rsp.rc_id,
903 p_data->remote_rsp.key_state);
904
905 if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR) {
906 handle_rc_vendorunique_rsp(&p_data->remote_rsp);
907 } else {
908 handle_rc_passthrough_rsp(&p_data->remote_rsp);
909 }
910 } break;
911
912 case BTA_AV_RC_FEAT_EVT: {
913 log::verbose("Peer_features: {:x}", p_data->rc_feat.peer_features);
914 p_dev = btif_rc_get_device_by_handle(p_data->rc_feat.rc_handle);
915 if (p_dev == NULL) {
916 log::error("RC Feature event for Invalid rc handle");
917 break;
918 }
919 log::verbose("peer_ct_features:0x{:x}, peer_tg_features=0x{:x}",
920 p_data->rc_feat.peer_ct_features, p_data->rc_feat.peer_tg_features);
921 if (btif_av_src_sink_coexist_enabled() &&
922 (p_dev->peer_ct_features == p_data->rc_feat.peer_ct_features) &&
923 (p_dev->peer_tg_features == p_data->rc_feat.peer_tg_features)) {
924 log::error("do SDP twice, no need callback rc_feature to framework again");
925 break;
926 }
927
928 p_dev->peer_ct_features = p_data->rc_feat.peer_ct_features;
929 p_dev->peer_tg_features = p_data->rc_feat.peer_tg_features;
930 p_dev->rc_features = p_data->rc_feat.peer_features;
931
932 if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) {
933 handle_rc_ctrl_features(p_dev);
934 }
935 } break;
936
937 case BTA_AV_RC_PSM_EVT: {
938 log::verbose("Peer cover art PSM: {:x}", p_data->rc_cover_art_psm.cover_art_psm);
939 p_dev = btif_rc_get_device_by_handle(p_data->rc_cover_art_psm.rc_handle);
940 if (p_dev == NULL) {
941 log::error("RC PSM event for Invalid rc handle");
942 break;
943 }
944
945 p_dev->rc_cover_art_psm = p_data->rc_cover_art_psm.cover_art_psm;
946 if ((p_dev->rc_connected) && (bt_rc_ctrl_callbacks != NULL)) {
947 handle_rc_ctrl_psm(p_dev);
948 }
949 } break;
950
951 case BTA_AV_META_MSG_EVT: {
952 if (bt_rc_ctrl_callbacks != NULL) {
953 /* This is case of Sink + CT + TG(for abs vol)) */
954 log::verbose("BTA_AV_META_MSG_EVT code:{} label:{} opcode {} ctype {}",
955 p_data->meta_msg.code, p_data->meta_msg.label,
956 p_data->meta_msg.p_msg->hdr.opcode, p_data->meta_msg.p_msg->hdr.ctype);
957 log::verbose("company_id:0x{:x} len:{} handle:{}", p_data->meta_msg.company_id,
958 p_data->meta_msg.len, p_data->meta_msg.rc_handle);
959 switch (p_data->meta_msg.p_msg->hdr.opcode) {
960 case AVRC_OP_VENDOR:
961 if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL) &&
962 (p_data->meta_msg.code <= AVRC_RSP_INTERIM)) {
963 /* Its a response */
964 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
965 } else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ) {
966 /* Its a command */
967 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
968 }
969 break;
970
971 case AVRC_OP_BROWSE:
972 if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_CMD) {
973 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
974 } else if (p_data->meta_msg.p_msg->hdr.ctype == AVRC_RSP) {
975 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
976 }
977 break;
978 }
979 } else {
980 log::error("Neither CTRL, nor TG is up, drop meta commands");
981 }
982 } break;
983
984 default:
985 log::verbose("Unhandled RC event : 0x{:x}", event);
986 }
987 }
988
btif_rc_is_connected_peer(const RawAddress & peer_addr)989 bool btif_rc_is_connected_peer(const RawAddress& peer_addr) {
990 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
991 btif_rc_device_cb_t* p_dev = get_connected_device(idx);
992 if (p_dev != NULL && p_dev->rc_connected && peer_addr == p_dev->rc_addr) {
993 return true;
994 }
995 }
996 return false;
997 }
998
999 /***************************************************************************
1000 **
1001 ** Function btif_rc_get_connected_peer_handle
1002 **
1003 ** Description Fetches the connected headset's handle if any
1004 **
1005 ***************************************************************************/
btif_rc_get_connected_peer_handle(const RawAddress & peer_addr)1006 uint8_t btif_rc_get_connected_peer_handle(const RawAddress& peer_addr) {
1007 btif_rc_device_cb_t* p_dev = NULL;
1008 p_dev = btif_rc_get_device_by_bda(peer_addr);
1009
1010 if (p_dev == NULL) {
1011 log::error("p_dev NULL");
1012 return BTRC_HANDLE_NONE;
1013 }
1014 return p_dev->rc_handle;
1015 }
1016
1017 /* Generic reject response */
send_reject_response(uint8_t rc_handle,uint8_t label,uint8_t pdu,uint8_t status,uint8_t opcode)1018 static void send_reject_response(uint8_t rc_handle, uint8_t label, uint8_t pdu, uint8_t status,
1019 uint8_t opcode) {
1020 uint8_t ctype = AVRC_RSP_REJ;
1021 tAVRC_RESPONSE avrc_rsp;
1022 BT_HDR* p_msg = NULL;
1023 memset(&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1024
1025 avrc_rsp.rsp.opcode = opcode;
1026 avrc_rsp.rsp.pdu = pdu;
1027 avrc_rsp.rsp.status = status;
1028
1029 status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg);
1030
1031 if (status != AVRC_STS_NO_ERROR) {
1032 log::error("status not AVRC_STS_NO_ERROR");
1033 return;
1034 }
1035
1036 log::verbose("Sending error notification to handle: {}. pdu: {},status: 0x{:02x}", rc_handle,
1037 dump_rc_pdu(pdu), status);
1038 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1039 }
1040
1041 /*******************************************************************************
1042 *
1043 * Function btif_rc_ctrl_upstreams_rsp_cmd
1044 *
1045 * Description Executes AVRC UPSTREAMS response events in btif context.
1046 *
1047 * Returns void
1048 *
1049 ******************************************************************************/
btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event,tAVRC_COMMAND * pavrc_cmd,uint8_t label,btif_rc_device_cb_t * p_dev)1050 static void btif_rc_ctrl_upstreams_rsp_cmd(uint8_t event, tAVRC_COMMAND* pavrc_cmd, uint8_t label,
1051 btif_rc_device_cb_t* p_dev) {
1052 log::verbose("pdu: {}: handle: 0x{:x}", dump_rc_pdu(pavrc_cmd->pdu), p_dev->rc_handle);
1053 switch (event) {
1054 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1055 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->setabsvol_cmd_cb, p_dev->rc_addr,
1056 pavrc_cmd->volume.volume, label));
1057 break;
1058 case AVRC_PDU_REGISTER_NOTIFICATION:
1059 if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE) {
1060 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->registernotification_absvol_cb,
1061 p_dev->rc_addr, label));
1062 }
1063 break;
1064 }
1065 }
1066
1067 /*******************************************************************************
1068 * AVRCP API Functions
1069 ******************************************************************************/
1070
1071 /*******************************************************************************
1072 *
1073 * Function init_ctrl
1074 *
1075 * Description Initializes the AVRC interface
1076 *
1077 * Returns bt_status_t
1078 *
1079 ******************************************************************************/
init_ctrl(btrc_ctrl_callbacks_t * callbacks)1080 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks) {
1081 log::verbose("");
1082 bt_status_t result = BT_STATUS_SUCCESS;
1083
1084 if (bt_rc_ctrl_callbacks) {
1085 return BT_STATUS_DONE;
1086 }
1087
1088 bt_rc_ctrl_callbacks = callbacks;
1089
1090 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
1091 initialize_device(&btif_rc_cb.rc_multi_cb[idx]);
1092 }
1093
1094 return result;
1095 }
1096
rc_ctrl_procedure_complete(btif_rc_device_cb_t * p_dev)1097 static void rc_ctrl_procedure_complete(btif_rc_device_cb_t* p_dev) {
1098 if (p_dev == NULL) {
1099 log::error("p_dev NULL");
1100 return;
1101 }
1102
1103 if (p_dev->rc_procedure_complete) {
1104 return;
1105 }
1106 p_dev->rc_procedure_complete = true;
1107 const uint32_t* attr_list = get_requested_attributes_list(p_dev);
1108 const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
1109 get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1110 }
1111
1112 /***************************************************************************
1113 *
1114 * Function iterate_supported_event_list_for_interim_rsp
1115 *
1116 * Description iterator callback function to match the event and handle
1117 * timer cleanup
1118 * Returns true to continue iterating, false to stop
1119 *
1120 **************************************************************************/
iterate_supported_event_list_for_interim_rsp(void * data,void * cb_data)1121 static bool iterate_supported_event_list_for_interim_rsp(void* data, void* cb_data) {
1122 uint8_t* p_event_id;
1123 btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)data;
1124
1125 p_event_id = (uint8_t*)cb_data;
1126
1127 if (p_event->event_id == *p_event_id) {
1128 p_event->status = eINTERIM;
1129 return false;
1130 }
1131 return true;
1132 }
1133
1134 /***************************************************************************
1135 *
1136 * Function rc_notification_interim_timeout
1137 *
1138 * Description Interim response timeout handler.
1139 * Runs the iterator to check and clear the timed out event.
1140 * Proceeds to register for the unregistered events.
1141 * Returns None
1142 *
1143 **************************************************************************/
rc_notification_interim_timeout(btif_rc_device_cb_t * p_dev,uint8_t event_id)1144 static void rc_notification_interim_timeout(btif_rc_device_cb_t* p_dev, uint8_t event_id) {
1145 /* Device disconnections clear the event list but can't free the timer */
1146 if (p_dev == NULL || p_dev->rc_supported_event_list == NULL) {
1147 log::warn("timeout for null device or event list");
1148 return;
1149 }
1150
1151 // Remove the timed out event from the supported events list
1152 list_node_t* node = list_begin(p_dev->rc_supported_event_list);
1153 while (node != NULL) {
1154 btif_rc_supported_event_t* p_event = (btif_rc_supported_event_t*)list_node(node);
1155 if (p_event != nullptr && p_event->event_id == event_id) {
1156 list_remove(p_dev->rc_supported_event_list, p_event);
1157 break;
1158 }
1159 node = list_next(node);
1160 }
1161
1162 /* Timeout happened for interim response for the registered event,
1163 * check if there are any pending for registration
1164 */
1165 node = list_begin(p_dev->rc_supported_event_list);
1166 while (node != NULL) {
1167 btif_rc_supported_event_t* p_event;
1168
1169 p_event = (btif_rc_supported_event_t*)list_node(node);
1170 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
1171 register_for_event_notification(p_event, p_dev);
1172 break;
1173 }
1174 node = list_next(node);
1175 }
1176 /* Todo. Need to initiate application settings query if this
1177 * is the last event registration.
1178 */
1179 }
1180
1181 /***************************************************************************
1182 *
1183 * Function register_for_event_notification
1184 *
1185 * Description Helper function registering notification events
1186 * sets an interim response timeout to handle if the remote
1187 * does not respond.
1188 * Returns None
1189 *
1190 **************************************************************************/
register_for_event_notification(btif_rc_supported_event_t * p_event,btif_rc_device_cb_t * p_dev)1191 static void register_for_event_notification(btif_rc_supported_event_t* p_event,
1192 btif_rc_device_cb_t* p_dev) {
1193 // interval is only valid for AVRC_EVT_PLAY_POS_CHANGED
1194 uint32_t interval_in_seconds = 0;
1195 if (p_event->event_id == AVRC_EVT_PLAY_POS_CHANGED) {
1196 interval_in_seconds = 2;
1197 }
1198 bt_status_t status = register_notification_cmd(p_event->event_id, interval_in_seconds, p_dev);
1199 if (status != BT_STATUS_SUCCESS) {
1200 log::error("failed, status={}", status);
1201 return;
1202 }
1203
1204 p_event->status = eREGISTERED;
1205 }
1206
1207 /***************************************************************************
1208 *
1209 * Function build_and_send_vendor_cmd
1210 *
1211 * Description Send a command to a device on the browsing channel
1212 *
1213 * Parameters avrc_cmd: The command you're sending
1214 * p_dev: Device control block
1215 *
1216 * Returns BT_STATUS_SUCCESS if command is issued successfully
1217 * otherwise BT_STATUS_FAIL
1218 *
1219 **************************************************************************/
build_and_send_vendor_cmd(tAVRC_COMMAND * avrc_cmd,tBTA_AV_CODE cmd_code,btif_rc_device_cb_t * p_dev)1220 static bt_status_t build_and_send_vendor_cmd(tAVRC_COMMAND* avrc_cmd, tBTA_AV_CODE cmd_code,
1221 btif_rc_device_cb_t* p_dev) {
1222 rc_transaction_t* p_transaction = NULL;
1223 rc_transaction_context_t context = {.rc_addr = p_dev->rc_addr,
1224 .label = MAX_LABEL,
1225 .opcode = AVRC_OP_VENDOR,
1226 .command = {.vendor = {avrc_cmd->pdu, AVRC_EVT_INVALID}}};
1227
1228 // Set the event ID in the context if this is a notification registration
1229 if (avrc_cmd->pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
1230 context.command.vendor.event_id = avrc_cmd->reg_notif.event_id;
1231 }
1232
1233 bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
1234 if (BT_STATUS_SUCCESS != tran_status || p_transaction == NULL) {
1235 log::error("failed to get label, pdu_id={}, status=0x{:02x}", dump_rc_pdu(avrc_cmd->pdu),
1236 tran_status);
1237 return BT_STATUS_FAIL;
1238 }
1239
1240 BT_HDR* p_msg = NULL;
1241 tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg);
1242 if (status == AVRC_STS_NO_ERROR && p_msg != NULL) {
1243 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
1244 log::verbose("{} msgreq being sent out with label: {}", dump_rc_pdu(avrc_cmd->pdu),
1245 p_transaction->label);
1246 BTA_AvVendorCmd(p_dev->rc_handle, p_transaction->label, cmd_code, data_start, p_msg->len);
1247 status = BT_STATUS_SUCCESS;
1248 start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
1249 } else {
1250 log::error("failed to build command. status: 0x{:02x}", status);
1251 release_transaction(p_dev, p_transaction->label);
1252 }
1253 osi_free(p_msg);
1254 return (bt_status_t)status;
1255 }
1256
1257 /***************************************************************************
1258 *
1259 * Function build_and_send_browsing_cmd
1260 *
1261 * Description Send a command to a device on the browsing channel
1262 *
1263 * Parameters avrc_cmd: The command you're sending
1264 * p_dev: Device control block
1265 *
1266 * Returns BT_STATUS_SUCCESS if command is issued successfully
1267 * otherwise BT_STATUS_FAIL
1268 *
1269 **************************************************************************/
build_and_send_browsing_cmd(tAVRC_COMMAND * avrc_cmd,btif_rc_device_cb_t * p_dev)1270 static bt_status_t build_and_send_browsing_cmd(tAVRC_COMMAND* avrc_cmd,
1271 btif_rc_device_cb_t* p_dev) {
1272 rc_transaction_t* p_transaction = NULL;
1273 rc_transaction_context_t context = {.rc_addr = p_dev->rc_addr,
1274 .label = MAX_LABEL,
1275 .opcode = AVRC_OP_BROWSE,
1276 .command = {.browse = {avrc_cmd->pdu}}};
1277
1278 bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
1279 if (tran_status != BT_STATUS_SUCCESS || p_transaction == NULL) {
1280 log::error("failed to get label, pdu_id={}, status=0x{:02x}", dump_rc_pdu(avrc_cmd->pdu),
1281 tran_status);
1282 return BT_STATUS_FAIL;
1283 }
1284
1285 BT_HDR* p_msg = NULL;
1286 tAVRC_STS status = AVRC_BldCommand(avrc_cmd, &p_msg);
1287 if (status != AVRC_STS_NO_ERROR) {
1288 log::error("failed to build command status {}", status);
1289 release_transaction(p_dev, p_transaction->label);
1290 return BT_STATUS_FAIL;
1291 }
1292
1293 log::verbose("Send pdu_id={}, label={}", dump_rc_pdu(avrc_cmd->pdu), p_transaction->label);
1294 BTA_AvMetaCmd(p_dev->rc_handle, p_transaction->label, AVRC_CMD_CTRL, p_msg);
1295 start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
1296 return BT_STATUS_SUCCESS;
1297 }
1298
1299 /***************************************************************************
1300 *
1301 * Function handle_get_capability_response
1302 *
1303 * Description Handles the get_cap_response to populate company id info
1304 * and query the supported events.
1305 * Initiates Notification registration for events supported
1306 * Returns None
1307 *
1308 **************************************************************************/
handle_get_capability_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CAPS_RSP * p_rsp)1309 static void handle_get_capability_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_GET_CAPS_RSP* p_rsp) {
1310 int xx = 0;
1311 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1312
1313 /* Todo: Do we need to retry on command timeout */
1314 if (p_rsp->status != AVRC_STS_NO_ERROR) {
1315 log::error("Error capability response: 0x{:02X}", p_rsp->status);
1316 return;
1317 }
1318
1319 if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED) {
1320 btif_rc_supported_event_t* p_event;
1321
1322 /* Todo: Check if list can be active when we hit here */
1323 p_dev->rc_supported_event_list = list_new(osi_free);
1324 for (xx = 0; xx < p_rsp->count; xx++) {
1325 /* Skip registering for Play position change notification */
1326 if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE) ||
1327 (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE) ||
1328 (p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_POS_CHANGED) ||
1329 (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE) ||
1330 (p_rsp->param.event_id[xx] == AVRC_EVT_NOW_PLAYING_CHANGE) ||
1331 (p_rsp->param.event_id[xx] == AVRC_EVT_ADDR_PLAYER_CHANGE) ||
1332 (p_rsp->param.event_id[xx] == AVRC_EVT_UIDS_CHANGE) ||
1333 (p_rsp->param.event_id[xx] == AVRC_EVT_AVAL_PLAYERS_CHANGE)) {
1334 p_event = (btif_rc_supported_event_t*)osi_malloc(sizeof(btif_rc_supported_event_t));
1335 p_event->event_id = p_rsp->param.event_id[xx];
1336 p_event->status = eNOT_REGISTERED;
1337 list_append(p_dev->rc_supported_event_list, p_event);
1338 }
1339 }
1340
1341 // On occasion a remote device can intermittently send a poorly configured
1342 // packet with 0 capabilities. This check ensures the stack does not crash.
1343 // Typically the remote device will send a proper packet in the future and
1344 // continue operation.
1345 if (list_is_empty(p_dev->rc_supported_event_list)) {
1346 return;
1347 }
1348
1349 p_event = (btif_rc_supported_event_t*)list_front(p_dev->rc_supported_event_list);
1350 if (p_event != NULL) {
1351 register_for_event_notification(p_event, p_dev);
1352 }
1353 } else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID) {
1354 getcapabilities_cmd(AVRC_CAP_EVENTS_SUPPORTED, p_dev);
1355 log::verbose("AVRC_CAP_COMPANY_ID:");
1356 for (xx = 0; xx < p_rsp->count; xx++) {
1357 log::verbose("company_id: {}", p_rsp->param.company_id[xx]);
1358 }
1359 }
1360 }
1361
rc_is_track_id_valid(tAVRC_UID uid)1362 static bool rc_is_track_id_valid(tAVRC_UID uid) {
1363 tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
1364
1365 if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0) {
1366 return false;
1367 } else {
1368 return true;
1369 }
1370 }
1371
1372 /***************************************************************************
1373 *
1374 * Function handle_notification_response
1375 *
1376 * Description Main handler for notification responses to registered events
1377 * 1. Register for unregistered event(in interim response path)
1378 * 2. After registering for all supported events, start
1379 * retrieving application settings and values
1380 * 3. Reregister for events on getting changed response
1381 * 4. Run play status timer for getting position when the
1382 * status changes to playing
1383 * 5. Get the Media details when the track change happens
1384 * or track change interim response is received with
1385 * valid track id
1386 * 6. HAL callback for play status change and application
1387 * setting change
1388 * Returns None
1389 *
1390 **************************************************************************/
handle_notification_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_REG_NOTIF_RSP * p_rsp)1391 static void handle_notification_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_REG_NOTIF_RSP* p_rsp) {
1392 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1393
1394 if (p_dev == NULL) {
1395 log::error("p_dev NULL");
1396 return;
1397 }
1398
1399 if (btif_av_src_sink_coexist_enabled() && p_rsp->event_id == AVRC_EVT_VOLUME_CHANGE) {
1400 log::error("legacy TG don't handle absolute volume change. leave it to new avrcp");
1401 return;
1402 }
1403
1404 const uint32_t* attr_list = get_requested_attributes_list(p_dev);
1405 const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
1406
1407 if (pmeta_msg->code == AVRC_RSP_INTERIM) {
1408 btif_rc_supported_event_t* p_event;
1409 list_node_t* node;
1410
1411 log::verbose("Interim response: 0x{:2X}", p_rsp->event_id);
1412 switch (p_rsp->event_id) {
1413 case AVRC_EVT_PLAY_STATUS_CHANGE:
1414 get_play_status_cmd(p_dev);
1415 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb,
1416 p_dev->rc_addr,
1417 (btrc_play_status_t)p_rsp->param.play_status));
1418 break;
1419
1420 case AVRC_EVT_TRACK_CHANGE:
1421 if (rc_is_track_id_valid(p_rsp->param.track) != true) {
1422 break;
1423 } else {
1424 uint8_t* p_data = p_rsp->param.track;
1425 BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
1426 get_play_status_cmd(p_dev);
1427 get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1428 }
1429 break;
1430
1431 case AVRC_EVT_APP_SETTING_CHANGE:
1432 break;
1433
1434 case AVRC_EVT_NOW_PLAYING_CHANGE:
1435 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->now_playing_contents_changed_cb,
1436 p_dev->rc_addr));
1437 break;
1438
1439 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
1440 log::verbose("AVRC_EVT_AVAL_PLAYERS_CHANGE");
1441 do_in_jni_thread(
1442 base::BindOnce(bt_rc_ctrl_callbacks->available_player_changed_cb, p_dev->rc_addr));
1443 break;
1444
1445 case AVRC_EVT_ADDR_PLAYER_CHANGE:
1446 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->addressed_player_changed_cb,
1447 p_dev->rc_addr, p_rsp->param.addr_player.player_id));
1448 break;
1449
1450 case AVRC_EVT_PLAY_POS_CHANGED:
1451 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb,
1452 p_dev->rc_addr, 0, p_rsp->param.play_pos));
1453
1454 break;
1455 case AVRC_EVT_UIDS_CHANGE:
1456 break;
1457
1458 case AVRC_EVT_TRACK_REACHED_END:
1459 case AVRC_EVT_TRACK_REACHED_START:
1460 case AVRC_EVT_BATTERY_STATUS_CHANGE:
1461 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
1462 default:
1463 log::error("Unhandled interim response: 0x{:2X}", p_rsp->event_id);
1464 return;
1465 }
1466
1467 list_foreach(p_dev->rc_supported_event_list, iterate_supported_event_list_for_interim_rsp,
1468 &p_rsp->event_id);
1469
1470 node = list_begin(p_dev->rc_supported_event_list);
1471
1472 while (node != NULL) {
1473 p_event = (btif_rc_supported_event_t*)list_node(node);
1474 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED)) {
1475 register_for_event_notification(p_event, p_dev);
1476 break;
1477 }
1478 node = list_next(node);
1479 p_event = NULL;
1480 }
1481 /* Registered for all events, we can request application settings */
1482 if (p_event == NULL && !p_dev->rc_app_settings.query_started) {
1483 /* we need to do this only if remote TG supports
1484 * player application settings
1485 */
1486 p_dev->rc_app_settings.query_started = true;
1487 if (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING) {
1488 list_player_app_setting_attrib_cmd(p_dev);
1489 } else {
1490 log::verbose("App setting not supported, complete procedure");
1491 rc_ctrl_procedure_complete(p_dev);
1492 }
1493 }
1494 } else if (pmeta_msg->code == AVRC_RSP_CHANGED) {
1495 btif_rc_supported_event_t* p_event;
1496 list_node_t* node;
1497
1498 log::verbose("Notification completed: 0x{:2X}", p_rsp->event_id);
1499
1500 node = list_begin(p_dev->rc_supported_event_list);
1501
1502 while (node != NULL) {
1503 p_event = (btif_rc_supported_event_t*)list_node(node);
1504 if (p_event != NULL && p_event->event_id == p_rsp->event_id) {
1505 p_event->status = eNOT_REGISTERED;
1506 register_for_event_notification(p_event, p_dev);
1507 break;
1508 }
1509 node = list_next(node);
1510 }
1511
1512 switch (p_rsp->event_id) {
1513 case AVRC_EVT_PLAY_STATUS_CHANGE:
1514 /* Start timer to get play status periodically
1515 * if the play state is playing.
1516 */
1517 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb,
1518 p_dev->rc_addr,
1519 (btrc_play_status_t)p_rsp->param.play_status));
1520
1521 break;
1522
1523 case AVRC_EVT_TRACK_CHANGE:
1524 if (rc_is_track_id_valid(p_rsp->param.track) != true) {
1525 break;
1526 } else {
1527 uint8_t* p_data = p_rsp->param.track;
1528 BE_STREAM_TO_UINT64(p_dev->rc_playing_uid, p_data);
1529 get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
1530 }
1531 break;
1532
1533 case AVRC_EVT_APP_SETTING_CHANGE: {
1534 btrc_player_settings_t app_settings;
1535 uint16_t xx;
1536
1537 app_settings.num_attr = p_rsp->param.player_setting.num_attr;
1538 for (xx = 0; xx < app_settings.num_attr; xx++) {
1539 app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
1540 app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
1541 }
1542 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
1543 p_dev->rc_addr, app_settings));
1544 } break;
1545
1546 case AVRC_EVT_NOW_PLAYING_CHANGE:
1547 break;
1548
1549 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
1550 break;
1551
1552 case AVRC_EVT_ADDR_PLAYER_CHANGE:
1553 break;
1554
1555 case AVRC_EVT_PLAY_POS_CHANGED:
1556 // handle on interim
1557 break;
1558
1559 case AVRC_EVT_UIDS_CHANGE:
1560 break;
1561
1562 case AVRC_EVT_TRACK_REACHED_END:
1563 case AVRC_EVT_TRACK_REACHED_START:
1564 case AVRC_EVT_BATTERY_STATUS_CHANGE:
1565 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
1566 default:
1567 log::error("Unhandled completion response: 0x{:2X}", p_rsp->event_id);
1568 return;
1569 }
1570 }
1571 }
1572
1573 /***************************************************************************
1574 *
1575 * Function handle_app_attr_response
1576 *
1577 * Description handles the the application attributes response and
1578 * initiates procedure to fetch the attribute values
1579 * Returns None
1580 *
1581 **************************************************************************/
handle_app_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_ATTR_RSP * p_rsp)1582 static void handle_app_attr_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_ATTR_RSP* p_rsp) {
1583 uint8_t xx;
1584 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1585
1586 if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
1587 log::error("Error getting Player application settings: 0x{:2X}", p_rsp->status);
1588 rc_ctrl_procedure_complete(p_dev);
1589 return;
1590 }
1591 p_dev->rc_app_settings.num_attrs = 0;
1592 p_dev->rc_app_settings.num_ext_attrs = 0;
1593
1594 for (xx = 0; xx < p_rsp->num_attr; xx++) {
1595 uint8_t st_index;
1596
1597 if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT) {
1598 st_index = p_dev->rc_app_settings.num_ext_attrs;
1599 p_dev->rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
1600 p_dev->rc_app_settings.num_ext_attrs++;
1601 } else {
1602 st_index = p_dev->rc_app_settings.num_attrs;
1603 p_dev->rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
1604 p_dev->rc_app_settings.num_attrs++;
1605 }
1606 }
1607 p_dev->rc_app_settings.attr_index = 0;
1608 p_dev->rc_app_settings.ext_attr_index = 0;
1609 p_dev->rc_app_settings.ext_val_index = 0;
1610 if (p_rsp->num_attr) {
1611 list_player_app_setting_value_cmd(p_dev->rc_app_settings.attrs[0].attr_id, p_dev);
1612 } else {
1613 log::error("No Player application settings found");
1614 }
1615 }
1616
1617 /***************************************************************************
1618 *
1619 * Function handle_app_val_response
1620 *
1621 * Description handles the the attributes value response and if extended
1622 * menu is available, it initiates query for the attribute
1623 * text. If not, it initiates procedure to get the current
1624 * attribute values and calls the HAL callback for provding
1625 * application settings information.
1626 * Returns None
1627 *
1628 **************************************************************************/
handle_app_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_LIST_APP_VALUES_RSP * p_rsp)1629 static void handle_app_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_LIST_APP_VALUES_RSP* p_rsp) {
1630 uint8_t xx, attr_index;
1631 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1632 btif_rc_player_app_settings_t* p_app_settings;
1633 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1634
1635 /* Todo: Do we need to retry on command timeout */
1636 if (p_dev == NULL || p_rsp->status != AVRC_STS_NO_ERROR) {
1637 log::error("Error fetching attribute values: 0x{:02X}", p_rsp->status);
1638 return;
1639 }
1640
1641 p_app_settings = &p_dev->rc_app_settings;
1642
1643 if (p_app_settings->attr_index < p_app_settings->num_attrs) {
1644 attr_index = p_app_settings->attr_index;
1645 p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
1646 for (xx = 0; xx < p_rsp->num_val; xx++) {
1647 p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
1648 }
1649 attr_index++;
1650 p_app_settings->attr_index++;
1651 if (attr_index < p_app_settings->num_attrs) {
1652 list_player_app_setting_value_cmd(p_app_settings->attrs[p_app_settings->attr_index].attr_id,
1653 p_dev);
1654 } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
1655 attr_index = 0;
1656 p_app_settings->ext_attr_index = 0;
1657 list_player_app_setting_value_cmd(p_app_settings->ext_attrs[attr_index].attr_id, p_dev);
1658 } else {
1659 for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1660 attrs[xx] = p_app_settings->attrs[xx].attr_id;
1661 }
1662 get_player_app_setting_cmd(p_app_settings->num_attrs, attrs, p_dev);
1663 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1664 p_dev->rc_addr, p_app_settings->num_attrs,
1665 p_app_settings->attrs, 0, nullptr));
1666 }
1667 } else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs) {
1668 attr_index = p_app_settings->ext_attr_index;
1669 p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
1670 for (xx = 0; xx < p_rsp->num_val; xx++) {
1671 p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
1672 }
1673 attr_index++;
1674 p_app_settings->ext_attr_index++;
1675 if (attr_index < p_app_settings->num_ext_attrs) {
1676 list_player_app_setting_value_cmd(
1677 p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id, p_dev);
1678 } else {
1679 uint8_t attr[AVRC_MAX_APP_ATTR_SIZE];
1680
1681 for (uint8_t xx = 0; xx < p_app_settings->num_ext_attrs; xx++) {
1682 attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
1683 }
1684 get_player_app_setting_attr_text_cmd(attr, p_app_settings->num_ext_attrs, p_dev);
1685 }
1686 }
1687 }
1688
1689 /***************************************************************************
1690 *
1691 * Function handle_app_cur_val_response
1692 *
1693 * Description handles the the get attributes value response.
1694 *
1695 * Returns None
1696 *
1697 **************************************************************************/
handle_app_cur_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_CUR_APP_VALUE_RSP * p_rsp)1698 static void handle_app_cur_val_response(tBTA_AV_META_MSG* pmeta_msg,
1699 tAVRC_GET_CUR_APP_VALUE_RSP* p_rsp) {
1700 btrc_player_settings_t app_settings;
1701 uint16_t xx;
1702 btif_rc_device_cb_t* p_dev = NULL;
1703
1704 /* Todo: Do we need to retry on command timeout */
1705 if (p_rsp->status != AVRC_STS_NO_ERROR) {
1706 log::error("Error fetching current settings: 0x{:02X}", p_rsp->status);
1707 return;
1708 }
1709 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1710 if (p_dev == NULL) {
1711 log::error("Error in getting Device Address");
1712 osi_free_and_reset((void**)&p_rsp->p_vals);
1713 return;
1714 }
1715
1716 app_settings.num_attr = p_rsp->num_val;
1717
1718 if (app_settings.num_attr > BTRC_MAX_APP_SETTINGS) {
1719 app_settings.num_attr = BTRC_MAX_APP_SETTINGS;
1720 }
1721
1722 for (xx = 0; xx < app_settings.num_attr; xx++) {
1723 app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
1724 app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
1725 }
1726
1727 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_changed_cb,
1728 p_dev->rc_addr, app_settings));
1729 /* Application settings are fetched only once for initial values
1730 * initiate anything that follows after RC procedure.
1731 * Defer it if browsing is supported till players query
1732 */
1733 rc_ctrl_procedure_complete(p_dev);
1734 osi_free_and_reset((void**)&p_rsp->p_vals);
1735 }
1736
1737 /***************************************************************************
1738 *
1739 * Function handle_app_attr_txt_response
1740 *
1741 * Description handles the the get attributes text response, if fails
1742 * calls HAL callback with just normal settings and initiates
1743 * query for current settings else initiates query for value
1744 * text
1745 * Returns None
1746 *
1747 **************************************************************************/
handle_app_attr_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)1748 static void handle_app_attr_txt_response(tBTA_AV_META_MSG* pmeta_msg,
1749 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
1750 uint8_t xx;
1751 uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
1752 btif_rc_player_app_settings_t* p_app_settings;
1753 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1754
1755 if (p_dev == NULL) {
1756 log::error("p_dev NULL");
1757 return;
1758 }
1759
1760 p_app_settings = &p_dev->rc_app_settings;
1761
1762 /* Todo: Do we need to retry on command timeout */
1763 if (p_rsp->status != AVRC_STS_NO_ERROR) {
1764 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1765
1766 log::error("Error fetching attribute text: 0x{:02X}", p_rsp->status);
1767 /* Not able to fetch Text for extended Menu, skip the process
1768 * and cleanup used memory. Proceed to get the current settings
1769 * for standard attributes.
1770 */
1771 p_app_settings->num_ext_attrs = 0;
1772 for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1773 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1774 }
1775 p_app_settings->ext_attr_index = 0;
1776
1777 for (xx = 0; xx < p_app_settings->num_attrs && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1778 attrs[xx] = p_app_settings->attrs[xx].attr_id;
1779 }
1780
1781 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1782 p_dev->rc_addr, p_app_settings->num_attrs,
1783 p_app_settings->attrs, 0, nullptr));
1784 get_player_app_setting_cmd(xx, attrs, p_dev);
1785
1786 return;
1787 }
1788
1789 for (xx = 0; xx < p_rsp->num_attr; xx++) {
1790 uint8_t x;
1791 for (x = 0; x < p_app_settings->num_ext_attrs && x < AVRC_MAX_APP_ATTR_SIZE; x++) {
1792 if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id) {
1793 p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
1794 p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
1795 p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
1796 break;
1797 }
1798 }
1799 }
1800
1801 for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val && xx < BTRC_MAX_APP_ATTR_SIZE; xx++) {
1802 vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
1803 }
1804 get_player_app_setting_value_text_cmd(vals, xx, p_dev);
1805 }
1806
1807 /***************************************************************************
1808 *
1809 * Function handle_app_attr_val_txt_response
1810 *
1811 * Description handles the the get attributes value text response, if fails
1812 * calls HAL callback with just normal settings and initiates
1813 * query for current settings
1814 * Returns None
1815 *
1816 **************************************************************************/
handle_app_attr_val_txt_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_APP_ATTR_TXT_RSP * p_rsp)1817 static void handle_app_attr_val_txt_response(tBTA_AV_META_MSG* pmeta_msg,
1818 tAVRC_GET_APP_ATTR_TXT_RSP* p_rsp) {
1819 uint8_t xx, attr_index;
1820 uint8_t vals[AVRC_MAX_APP_ATTR_SIZE];
1821 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1822 btif_rc_player_app_settings_t* p_app_settings;
1823 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1824
1825 if (p_dev == NULL) {
1826 log::error("p_dev NULL");
1827 return;
1828 }
1829
1830 p_app_settings = &p_dev->rc_app_settings;
1831
1832 /* Todo: Do we need to retry on command timeout */
1833 if (p_rsp->status != AVRC_STS_NO_ERROR) {
1834 uint8_t attrs[AVRC_MAX_APP_ATTR_SIZE];
1835
1836 log::error("Error fetching attribute value text: 0x{:02X}", p_rsp->status);
1837
1838 /* Not able to fetch Text for extended Menu, skip the process
1839 * and cleanup used memory. Proceed to get the current settings
1840 * for standard attributes.
1841 */
1842 p_app_settings->num_ext_attrs = 0;
1843 for (xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1844 int x;
1845 btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
1846
1847 for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1848 osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
1849 }
1850 p_ext_attr->num_val = 0;
1851 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1852 }
1853 p_app_settings->ext_attr_index = 0;
1854
1855 for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1856 attrs[xx] = p_app_settings->attrs[xx].attr_id;
1857 }
1858 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1859 p_dev->rc_addr, p_app_settings->num_attrs,
1860 p_app_settings->attrs, 0, nullptr));
1861
1862 get_player_app_setting_cmd(xx, attrs, p_dev);
1863 return;
1864 }
1865
1866 if (p_app_settings->ext_val_index >= AVRC_MAX_APP_ATTR_SIZE) {
1867 log::error("ext_val_index is 0x{:02x}, overflow!", p_app_settings->ext_val_index);
1868 return;
1869 }
1870
1871 for (xx = 0; xx < p_rsp->num_attr; xx++) {
1872 uint8_t x;
1873 btrc_player_app_ext_attr_t* p_ext_attr;
1874 p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
1875 for (x = 0; x < p_rsp->num_attr && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1876 if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id) {
1877 p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
1878 p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
1879 p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
1880 break;
1881 }
1882 }
1883 }
1884 p_app_settings->ext_val_index++;
1885
1886 if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs) {
1887 attr_index = p_app_settings->ext_val_index;
1888 for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++) {
1889 vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
1890 }
1891 get_player_app_setting_value_text_cmd(vals, xx, p_dev);
1892 } else {
1893 uint8_t x;
1894
1895 for (xx = 0; xx < p_app_settings->num_attrs; xx++) {
1896 attrs[xx] = p_app_settings->attrs[xx].attr_id;
1897 }
1898 for (x = 0; x < p_app_settings->num_ext_attrs; x++) {
1899 attrs[xx + x] = p_app_settings->ext_attrs[x].attr_id;
1900 }
1901 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->playerapplicationsetting_cb,
1902 p_dev->rc_addr, p_app_settings->num_attrs,
1903 p_app_settings->attrs, p_app_settings->num_ext_attrs,
1904 p_app_settings->ext_attrs));
1905 get_player_app_setting_cmd(xx + x, attrs, p_dev);
1906
1907 /* Free the application settings information after sending to
1908 * application.
1909 */
1910 do_in_jni_thread(base::BindOnce(cleanup_app_attr_val_txt_response, p_app_settings));
1911 p_app_settings->num_attrs = 0;
1912 }
1913 }
1914
1915 /***************************************************************************
1916 *
1917 * Function cleanup_app_attr_val_txt_response
1918 *
1919 * Description Frees the memory that was allocated for reporting player
1920 * application settings.
1921 * Returns None
1922 **************************************************************************/
cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t * p_app_settings)1923 static void cleanup_app_attr_val_txt_response(btif_rc_player_app_settings_t* p_app_settings) {
1924 for (uint8_t xx = 0; xx < p_app_settings->ext_attr_index && xx < AVRC_MAX_APP_ATTR_SIZE; xx++) {
1925 int x;
1926 btrc_player_app_ext_attr_t* p_ext_attr = &p_app_settings->ext_attrs[xx];
1927 for (x = 0; x < p_ext_attr->num_val && x < BTRC_MAX_APP_ATTR_SIZE; x++) {
1928 osi_free_and_reset((void**)&p_ext_attr->ext_attr_val[x].p_str);
1929 }
1930 p_ext_attr->num_val = 0;
1931 osi_free_and_reset((void**)&p_app_settings->ext_attrs[xx].p_str);
1932 }
1933 }
1934
1935 /***************************************************************************
1936 *
1937 * Function handle_set_app_attr_val_response
1938 *
1939 * Description handles the the set attributes value response, if fails
1940 * calls HAL callback to indicate the failure
1941 * Returns None
1942 *
1943 **************************************************************************/
handle_set_app_attr_val_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP *)1944 static void handle_set_app_attr_val_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* /*p_rsp*/) {
1945 uint8_t accepted = 0;
1946 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1947
1948 if (p_dev == NULL) {
1949 log::error("p_dev NULL");
1950 return;
1951 }
1952
1953 /* For timeout pmeta_msg will be NULL, else we need to
1954 * check if this is accepted by TG
1955 */
1956 if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT)) {
1957 accepted = 1;
1958 }
1959 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->setplayerappsetting_rsp_cb, p_dev->rc_addr,
1960 accepted));
1961 }
1962
1963 /***************************************************************************
1964 *
1965 * Function handle_get_metadata_attr_response
1966 *
1967 * Description handles the the element attributes response, calls
1968 * HAL callback to update track change information.
1969 * Returns None
1970 *
1971 **************************************************************************/
handle_get_metadata_attr_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ATTRS_RSP * p_rsp)1972 static void handle_get_metadata_attr_response(tBTA_AV_META_MSG* pmeta_msg,
1973 tAVRC_GET_ATTRS_RSP* p_rsp) {
1974 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
1975
1976 if (p_rsp->status == AVRC_STS_NO_ERROR) {
1977 size_t buf_size = p_rsp->num_attrs * sizeof(btrc_element_attr_val_t);
1978 btrc_element_attr_val_t* p_attr = (btrc_element_attr_val_t*)osi_calloc(buf_size);
1979
1980 if (p_dev == NULL) {
1981 log::error("p_dev NULL");
1982 return;
1983 }
1984
1985 for (int i = 0; i < p_rsp->num_attrs; i++) {
1986 p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
1987 /* Todo. Length limit check to include null */
1988 if (p_rsp->p_attrs[i].name.str_len && p_rsp->p_attrs[i].name.p_str) {
1989 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str, p_rsp->p_attrs[i].name.str_len);
1990 osi_free_and_reset((void**)&p_rsp->p_attrs[i].name.p_str);
1991 }
1992 }
1993
1994 osi_free_and_reset((void**)&p_rsp->p_attrs);
1995
1996 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->track_changed_cb, p_dev->rc_addr,
1997 p_rsp->num_attrs, p_attr));
1998 do_in_jni_thread(base::BindOnce(osi_free, p_attr));
1999 } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
2000 /* Retry for timeout case, this covers error handling
2001 * for continuation failure also.
2002 */
2003 const uint32_t* attr_list = get_requested_attributes_list(p_dev);
2004 const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
2005 get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
2006 } else {
2007 log::error("Error in get element attr procedure: {}", p_rsp->status);
2008 }
2009 }
2010
2011 /***************************************************************************
2012 *
2013 * Function handle_get_playstatus_response
2014 *
2015 * Description handles the the play status response, calls
2016 * HAL callback to update play position.
2017 * Returns None
2018 *
2019 **************************************************************************/
handle_get_playstatus_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_PLAY_STATUS_RSP * p_rsp)2020 static void handle_get_playstatus_response(tBTA_AV_META_MSG* pmeta_msg,
2021 tAVRC_GET_PLAY_STATUS_RSP* p_rsp) {
2022 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2023
2024 if (p_dev == NULL) {
2025 log::error("p_dev NULL");
2026 return;
2027 }
2028
2029 if (p_rsp->status == AVRC_STS_NO_ERROR) {
2030 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_status_changed_cb, p_dev->rc_addr,
2031 (btrc_play_status_t)p_rsp->play_status));
2032 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->play_position_changed_cb, p_dev->rc_addr,
2033 p_rsp->song_len, p_rsp->song_pos));
2034 } else {
2035 log::error("Error in get play status procedure: {}", p_rsp->status);
2036 }
2037 }
2038
2039 /***************************************************************************
2040 *
2041 * Function handle_set_addressed_player_response
2042 *
2043 * Description handles the the set addressed player response, calls
2044 * HAL callback
2045 * Returns None
2046 *
2047 **************************************************************************/
handle_set_addressed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_RSP * p_rsp)2048 static void handle_set_addressed_player_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_RSP* p_rsp) {
2049 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2050
2051 if (p_dev == NULL) {
2052 log::error("p_dev NULL");
2053 return;
2054 }
2055
2056 if (p_rsp->status == AVRC_STS_NO_ERROR) {
2057 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->set_addressed_player_cb, p_dev->rc_addr,
2058 p_rsp->status));
2059 } else {
2060 log::error("Error in get play status procedure {}", p_rsp->status);
2061 }
2062 }
2063
2064 /***************************************************************************
2065 *
2066 * Function handle_get_folder_items_response
2067 *
2068 * Description handles the the get folder items response, calls
2069 * HAL callback to send the folder items.
2070 * Returns None
2071 *
2072 **************************************************************************/
handle_get_folder_items_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_GET_ITEMS_RSP * p_rsp)2073 static void handle_get_folder_items_response(tBTA_AV_META_MSG* pmeta_msg,
2074 tAVRC_GET_ITEMS_RSP* p_rsp) {
2075 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2076
2077 if (p_rsp->status == AVRC_STS_NO_ERROR) {
2078 /* Convert the internal folder listing into a response that can
2079 * be passed onto JNI via HAL_CBACK
2080 */
2081 uint8_t item_count = p_rsp->item_count;
2082 btrc_folder_items_t* btrc_items =
2083 (btrc_folder_items_t*)osi_malloc(sizeof(btrc_folder_items_t) * item_count);
2084 for (uint8_t i = 0; i < item_count; i++) {
2085 const tAVRC_ITEM* avrc_item = &(p_rsp->p_item_list[i]);
2086 btrc_folder_items_t* btrc_item = &(btrc_items[i]);
2087 log::verbose("folder item type {}", avrc_item->item_type);
2088 switch (avrc_item->item_type) {
2089 case AVRC_ITEM_MEDIA:
2090 log::verbose("setting type to {}", BTRC_ITEM_MEDIA);
2091 /* Allocate Space for Attributes */
2092 btrc_item->media.num_attrs = avrc_item->u.media.attr_count;
2093 btrc_item->media.p_attrs = (btrc_element_attr_val_t*)osi_malloc(
2094 btrc_item->media.num_attrs * sizeof(btrc_element_attr_val_t));
2095 get_folder_item_type_media(avrc_item, btrc_item);
2096 break;
2097
2098 case AVRC_ITEM_FOLDER:
2099 log::verbose("setting type to BTRC_ITEM_FOLDER");
2100 get_folder_item_type_folder(avrc_item, btrc_item);
2101 break;
2102
2103 case AVRC_ITEM_PLAYER:
2104 log::verbose("setting type to BTRC_ITEM_PLAYER");
2105 get_folder_item_type_player(avrc_item, btrc_item);
2106 break;
2107
2108 default:
2109 log::error("cannot understand folder item type {}", avrc_item->item_type);
2110 }
2111 }
2112
2113 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
2114 BTRC_STS_NO_ERROR,
2115 /* We want to make the ownership explicit in native */
2116 btrc_items, item_count));
2117
2118 if (item_count > 0) {
2119 if (btrc_items[0].item_type == AVRC_ITEM_PLAYER &&
2120 (p_dev->rc_features & BTA_AV_FEAT_APP_SETTING)) {
2121 list_player_app_setting_attrib_cmd(p_dev);
2122 }
2123 }
2124 /* Release the memory block for items and attributes allocated here.
2125 * Since the executor for do_in_jni_thread is a Single Thread Task Runner it
2126 * is okay to queue up the cleanup of btrc_items */
2127 do_in_jni_thread(base::BindOnce(cleanup_btrc_folder_items, btrc_items, item_count));
2128
2129 log::verbose("get_folder_items_cb sent to JNI thread");
2130 } else {
2131 log::error("Error {}", p_rsp->status);
2132 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->get_folder_items_cb, p_dev->rc_addr,
2133 (btrc_status_t)p_rsp->status, nullptr, 0));
2134 }
2135 }
2136 /***************************************************************************
2137 *
2138 * Function cleanup_btrc_folder_items
2139 *
2140 * Description Frees the memory that was allocated for a list of folder
2141 * items.
2142 * Returns None
2143 **************************************************************************/
cleanup_btrc_folder_items(btrc_folder_items_t * btrc_items,uint8_t item_count)2144 static void cleanup_btrc_folder_items(btrc_folder_items_t* btrc_items, uint8_t item_count) {
2145 for (uint8_t i = 0; i < item_count; i++) {
2146 btrc_folder_items_t* btrc_item = &(btrc_items[i]);
2147 switch (btrc_item->item_type) {
2148 case BTRC_ITEM_MEDIA:
2149 osi_free(btrc_item->media.p_attrs);
2150 break;
2151 case BTRC_ITEM_PLAYER:
2152 case BTRC_ITEM_FOLDER:
2153 /*Nothing to free*/
2154 break;
2155 default:
2156 log::warn("free unspecified type");
2157 }
2158 }
2159 osi_free(btrc_items);
2160 }
2161
2162 /***************************************************************************
2163 *
2164 * Function get_folder_item_type_media
2165 *
2166 * Description Converts the AVRC representation of a folder item with
2167 * TYPE media to BTIF representation.
2168 * Returns None
2169 *
2170 **************************************************************************/
get_folder_item_type_media(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2171 static void get_folder_item_type_media(const tAVRC_ITEM* avrc_item,
2172 btrc_folder_items_t* btrc_item) {
2173 btrc_item->item_type = BTRC_ITEM_MEDIA;
2174 const tAVRC_ITEM_MEDIA* avrc_item_media = &(avrc_item->u.media);
2175 btrc_item_media_t* btrc_item_media = &(btrc_item->media);
2176 /* UID */
2177 memset(btrc_item_media->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
2178 memcpy(btrc_item_media->uid, avrc_item_media->uid, sizeof(uint8_t) * BTRC_UID_SIZE);
2179
2180 /* Audio/Video type */
2181 switch (avrc_item_media->type) {
2182 case AVRC_MEDIA_TYPE_AUDIO:
2183 btrc_item_media->type = BTRC_MEDIA_TYPE_AUDIO;
2184 break;
2185 case AVRC_MEDIA_TYPE_VIDEO:
2186 btrc_item_media->type = BTRC_MEDIA_TYPE_VIDEO;
2187 break;
2188 }
2189
2190 /* Charset ID */
2191 btrc_item_media->charset_id = avrc_item_media->name.charset_id;
2192
2193 /* Copy the name */
2194 log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, avrc_item_media->name.str_len);
2195 memset(btrc_item_media->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2196 memcpy(btrc_item_media->name, avrc_item_media->name.p_str,
2197 sizeof(uint8_t) * (avrc_item_media->name.str_len));
2198
2199 /* Extract each attribute */
2200 for (int i = 0; i < avrc_item_media->attr_count; i++) {
2201 btrc_element_attr_val_t* btrc_attr_pair = &(btrc_item_media->p_attrs[i]);
2202 tAVRC_ATTR_ENTRY* avrc_attr_pair = &(avrc_item_media->p_attr_list[i]);
2203
2204 log::verbose("media attr id 0x{:x}", avrc_attr_pair->attr_id);
2205
2206 switch (avrc_attr_pair->attr_id) {
2207 case AVRC_MEDIA_ATTR_ID_TITLE:
2208 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TITLE;
2209 break;
2210 case AVRC_MEDIA_ATTR_ID_ARTIST:
2211 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ARTIST;
2212 break;
2213 case AVRC_MEDIA_ATTR_ID_ALBUM:
2214 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_ALBUM;
2215 break;
2216 case AVRC_MEDIA_ATTR_ID_TRACK_NUM:
2217 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_TRACK_NUM;
2218 break;
2219 case AVRC_MEDIA_ATTR_ID_NUM_TRACKS:
2220 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_NUM_TRACKS;
2221 break;
2222 case AVRC_MEDIA_ATTR_ID_GENRE:
2223 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_GENRE;
2224 break;
2225 case AVRC_MEDIA_ATTR_ID_PLAYING_TIME:
2226 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_PLAYING_TIME;
2227 break;
2228 case AVRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE:
2229 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_COVER_ARTWORK_HANDLE;
2230 break;
2231 default:
2232 log::error("invalid media attr id: 0x{:x}", avrc_attr_pair->attr_id);
2233 btrc_attr_pair->attr_id = BTRC_MEDIA_ATTR_ID_INVALID;
2234 }
2235
2236 memset(btrc_attr_pair->text, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2237 memcpy(btrc_attr_pair->text, avrc_attr_pair->name.p_str, avrc_attr_pair->name.str_len);
2238 }
2239 }
2240
2241 /***************************************************************************
2242 *
2243 * Function get_folder_item_type_folder
2244 *
2245 * Description Converts the AVRC representation of a folder item with
2246 * TYPE folder to BTIF representation.
2247 * Returns None
2248 *
2249 **************************************************************************/
get_folder_item_type_folder(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2250 static void get_folder_item_type_folder(const tAVRC_ITEM* avrc_item,
2251 btrc_folder_items_t* btrc_item) {
2252 btrc_item->item_type = BTRC_ITEM_FOLDER;
2253 const tAVRC_ITEM_FOLDER* avrc_item_folder = &(avrc_item->u.folder);
2254 btrc_item_folder_t* btrc_item_folder = &(btrc_item->folder);
2255 /* Copy the UID */
2256 memset(btrc_item_folder->uid, 0, BTRC_UID_SIZE * sizeof(uint8_t));
2257 memcpy(btrc_item_folder->uid, avrc_item_folder->uid, sizeof(uint8_t) * BTRC_UID_SIZE);
2258
2259 /* Copy the type */
2260 switch (avrc_item_folder->type) {
2261 case AVRC_FOLDER_TYPE_MIXED:
2262 btrc_item_folder->type = BTRC_FOLDER_TYPE_MIXED;
2263 break;
2264 case AVRC_FOLDER_TYPE_TITLES:
2265 btrc_item_folder->type = BTRC_FOLDER_TYPE_TITLES;
2266 break;
2267 case AVRC_FOLDER_TYPE_ALNUMS:
2268 btrc_item_folder->type = BTRC_FOLDER_TYPE_ALBUMS;
2269 break;
2270 case AVRC_FOLDER_TYPE_ARTISTS:
2271 btrc_item_folder->type = BTRC_FOLDER_TYPE_ARTISTS;
2272 break;
2273 case AVRC_FOLDER_TYPE_GENRES:
2274 btrc_item_folder->type = BTRC_FOLDER_TYPE_GENRES;
2275 break;
2276 case AVRC_FOLDER_TYPE_PLAYLISTS:
2277 btrc_item_folder->type = BTRC_FOLDER_TYPE_PLAYLISTS;
2278 break;
2279 case AVRC_FOLDER_TYPE_YEARS:
2280 btrc_item_folder->type = BTRC_FOLDER_TYPE_YEARS;
2281 break;
2282 }
2283
2284 /* Copy if playable */
2285 btrc_item_folder->playable = avrc_item_folder->playable;
2286
2287 /* Copy name */
2288 log::verbose("max len {} str len {}", BTRC_MAX_ATTR_STR_LEN, avrc_item_folder->name.str_len);
2289 memset(btrc_item_folder->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2290 memcpy(btrc_item_folder->name, avrc_item_folder->name.p_str,
2291 avrc_item_folder->name.str_len * sizeof(uint8_t));
2292
2293 /* Copy charset */
2294 btrc_item_folder->charset_id = avrc_item_folder->name.charset_id;
2295 }
2296
2297 /***************************************************************************
2298 *
2299 * Function get_folder_item_type_player
2300 *
2301 * Description Converts the AVRC representation of a folder item with
2302 * TYPE player to BTIF representation.
2303 * Returns None
2304 *
2305 **************************************************************************/
get_folder_item_type_player(const tAVRC_ITEM * avrc_item,btrc_folder_items_t * btrc_item)2306 static void get_folder_item_type_player(const tAVRC_ITEM* avrc_item,
2307 btrc_folder_items_t* btrc_item) {
2308 btrc_item->item_type = BTRC_ITEM_PLAYER;
2309 const tAVRC_ITEM_PLAYER* avrc_item_player = &(avrc_item->u.player);
2310 btrc_item_player_t* btrc_item_player = &(btrc_item->player);
2311 /* Player ID */
2312 btrc_item_player->player_id = avrc_item_player->player_id;
2313 /* Major type */
2314 btrc_item_player->major_type = avrc_item_player->major_type;
2315 /* Sub type */
2316 btrc_item_player->sub_type = avrc_item_player->sub_type;
2317 /* Play status */
2318 btrc_item_player->play_status = avrc_item_player->play_status;
2319 /* Features */
2320 memcpy(btrc_item_player->features, avrc_item_player->features, BTRC_FEATURE_BIT_MASK_SIZE);
2321
2322 memset(btrc_item_player->name, 0, BTRC_MAX_ATTR_STR_LEN * sizeof(uint8_t));
2323 memcpy(btrc_item_player->name, avrc_item_player->name.p_str, avrc_item_player->name.str_len);
2324 }
2325
2326 /***************************************************************************
2327 *
2328 * Function handle_change_path_response
2329 *
2330 * Description handles the the change path response, calls
2331 * HAL callback to send the updated folder
2332 * Returns None
2333 *
2334 **************************************************************************/
handle_change_path_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_CHG_PATH_RSP * p_rsp)2335 static void handle_change_path_response(tBTA_AV_META_MSG* pmeta_msg, tAVRC_CHG_PATH_RSP* p_rsp) {
2336 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2337
2338 if (p_dev == NULL) {
2339 log::error("Invalid rc handle");
2340 return;
2341 }
2342
2343 if (p_rsp->status == AVRC_STS_NO_ERROR) {
2344 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->change_folder_path_cb, p_dev->rc_addr,
2345 p_rsp->num_items));
2346 } else {
2347 log::error("error in handle_change_path_response {}", p_rsp->status);
2348 }
2349 }
2350
2351 /***************************************************************************
2352 *
2353 * Function handle_set_browsed_player_response
2354 *
2355 * Description handles the the change path response, calls
2356 * HAL callback to send the updated folder
2357 * Returns None
2358 *
2359 **************************************************************************/
handle_set_browsed_player_response(tBTA_AV_META_MSG * pmeta_msg,tAVRC_SET_BR_PLAYER_RSP * p_rsp)2360 static void handle_set_browsed_player_response(tBTA_AV_META_MSG* pmeta_msg,
2361 tAVRC_SET_BR_PLAYER_RSP* p_rsp) {
2362 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2363
2364 if (p_dev == NULL) {
2365 log::error("Invalid rc handle");
2366 return;
2367 }
2368
2369 if (p_rsp->status == AVRC_STS_NO_ERROR) {
2370 do_in_jni_thread(base::BindOnce(bt_rc_ctrl_callbacks->set_browsed_player_cb, p_dev->rc_addr,
2371 p_rsp->num_items, p_rsp->folder_depth));
2372 } else {
2373 log::error("error {}", p_rsp->status);
2374 }
2375 }
2376
2377 /***************************************************************************
2378 *
2379 * Function clear_cmd_timeout
2380 *
2381 * Description helper function to stop the command timeout timer
2382 * Returns None
2383 *
2384 **************************************************************************/
clear_cmd_timeout(btif_rc_device_cb_t * p_dev,uint8_t label)2385 static void clear_cmd_timeout(btif_rc_device_cb_t* p_dev, uint8_t label) {
2386 rc_transaction_t* p_txn;
2387
2388 p_txn = get_transaction_by_lbl(p_dev, label);
2389 if (p_txn == NULL) {
2390 log::error("Error in transaction label lookup");
2391 return;
2392 }
2393
2394 if (p_txn->timer != NULL) {
2395 // Free also calls alarm_cancel() in its implementation
2396 alarm_free(p_txn->timer);
2397 }
2398 p_txn->timer = nullptr;
2399 }
2400
2401 /***************************************************************************
2402 *
2403 * Function handle_avk_rc_metamsg_rsp
2404 *
2405 * Description Handle RC metamessage response
2406 *
2407 * Returns void
2408 *
2409 **************************************************************************/
handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG * pmeta_msg)2410 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG* pmeta_msg) {
2411 tAVRC_RESPONSE avrc_response = {0};
2412 uint8_t scratch_buf[512] = {0}; // this variable is unused
2413 uint16_t buf_len;
2414 tAVRC_STS status;
2415 btif_rc_device_cb_t* p_dev = NULL;
2416
2417 log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
2418
2419 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2420 status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
2421 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code >= AVRC_RSP_NOT_IMPL) &&
2422 (pmeta_msg->code <= AVRC_RSP_INTERIM)) {
2423 log::verbose("parse status {} pdu = {} rsp_status = {}", status, avrc_response.pdu,
2424 pmeta_msg->p_msg->vendor.hdr.ctype);
2425
2426 switch (avrc_response.pdu) {
2427 case AVRC_PDU_REGISTER_NOTIFICATION:
2428 handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
2429 if (pmeta_msg->code == AVRC_RSP_INTERIM) {
2430 /* Don't free the transaction Id */
2431 clear_cmd_timeout(p_dev, pmeta_msg->label);
2432 return;
2433 }
2434 break;
2435
2436 case AVRC_PDU_GET_CAPABILITIES:
2437 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
2438 break;
2439
2440 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2441 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
2442 break;
2443
2444 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2445 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
2446 break;
2447
2448 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2449 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
2450 break;
2451
2452 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2453 handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
2454 break;
2455
2456 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2457 handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
2458 break;
2459
2460 case AVRC_PDU_SET_PLAYER_APP_VALUE:
2461 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
2462 break;
2463
2464 case AVRC_PDU_GET_ELEMENT_ATTR:
2465 handle_get_metadata_attr_response(pmeta_msg, &avrc_response.get_attrs);
2466 break;
2467
2468 case AVRC_PDU_GET_PLAY_STATUS:
2469 handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
2470 break;
2471
2472 case AVRC_PDU_SET_ADDRESSED_PLAYER:
2473 handle_set_addressed_player_response(pmeta_msg, &avrc_response.rsp);
2474 break;
2475 }
2476 } else if (AVRC_OP_BROWSE == pmeta_msg->p_msg->hdr.opcode) {
2477 log::verbose("AVRC_OP_BROWSE pdu {}", avrc_response.pdu);
2478 /* check what kind of command it is for browsing */
2479 switch (avrc_response.pdu) {
2480 case AVRC_PDU_GET_FOLDER_ITEMS:
2481 handle_get_folder_items_response(pmeta_msg, &avrc_response.get_items);
2482 break;
2483 case AVRC_PDU_CHANGE_PATH:
2484 handle_change_path_response(pmeta_msg, &avrc_response.chg_path);
2485 break;
2486 case AVRC_PDU_SET_BROWSED_PLAYER:
2487 handle_set_browsed_player_response(pmeta_msg, &avrc_response.br_player);
2488 break;
2489 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
2490 handle_get_metadata_attr_response(pmeta_msg, &avrc_response.get_attrs);
2491 break;
2492 default:
2493 log::error("cannot handle browse pdu {}", pmeta_msg->p_msg->hdr.opcode);
2494 }
2495 } else {
2496 log::verbose("Invalid Vendor Command code: {} len: {}. Not processing it.", pmeta_msg->code,
2497 pmeta_msg->len);
2498 return;
2499 }
2500 log::verbose("release transaction {}", pmeta_msg->label);
2501 release_transaction(p_dev, pmeta_msg->label);
2502 }
2503
2504 /***************************************************************************
2505 *
2506 * Function handle_avk_rc_metamsg_cmd
2507 *
2508 * Description Handle RC metamessage response
2509 *
2510 * Returns void
2511 *
2512 **************************************************************************/
handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG * pmeta_msg)2513 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG* pmeta_msg) {
2514 tAVRC_COMMAND avrc_cmd = {0};
2515 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
2516 btif_rc_device_cb_t* p_dev = NULL;
2517
2518 log::verbose("opcode: {} rsp_code: {}", pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
2519 status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
2520 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode) && (pmeta_msg->code <= AVRC_CMD_GEN_INQ)) {
2521 log::verbose("Received vendor command.code {}, PDU {} label {}", pmeta_msg->code, avrc_cmd.pdu,
2522 pmeta_msg->label);
2523
2524 if (status != AVRC_STS_NO_ERROR) {
2525 /* return error */
2526 log::warn("Error in parsing received metamsg command. status: 0x{:02x}", status);
2527 if (true == btif_av_both_enable()) {
2528 if (AVRC_PDU_GET_CAPABILITIES == avrc_cmd.pdu ||
2529 AVRC_PDU_GET_ELEMENT_ATTR == avrc_cmd.pdu || AVRC_PDU_GET_PLAY_STATUS == avrc_cmd.pdu ||
2530 AVRC_PDU_GET_FOLDER_ITEMS == avrc_cmd.pdu ||
2531 AVRC_PDU_GET_ITEM_ATTRIBUTES == avrc_cmd.pdu) {
2532 return;
2533 }
2534 }
2535 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status,
2536 pmeta_msg->p_msg->hdr.opcode);
2537 } else {
2538 p_dev = btif_rc_get_device_by_handle(pmeta_msg->rc_handle);
2539 if (p_dev == NULL) {
2540 log::error("avk rc meta msg cmd for Invalid rc handle");
2541 return;
2542 }
2543
2544 if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION) {
2545 uint8_t event_id = avrc_cmd.reg_notif.event_id;
2546 log::verbose("Register notification event_id: {}", dump_rc_notification_event_id(event_id));
2547 } else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME) {
2548 log::verbose("Abs Volume Cmd Recvd");
2549 }
2550
2551 btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label, p_dev);
2552 }
2553 } else {
2554 log::verbose("Invalid Vendor Command code: {} len: {}. Not processing it.", pmeta_msg->code,
2555 pmeta_msg->len);
2556 return;
2557 }
2558 }
2559
2560 /***************************************************************************
2561 *
2562 * Function cleanup_ctrl
2563 *
2564 * Description Closes the AVRC Controller interface
2565 *
2566 * Returns void
2567 *
2568 **************************************************************************/
cleanup_ctrl()2569 static void cleanup_ctrl() {
2570 log::verbose("");
2571
2572 if (bt_rc_ctrl_callbacks) {
2573 bt_rc_ctrl_callbacks = NULL;
2574 }
2575
2576 for (int idx = 0; idx < BTIF_RC_NUM_CONN; idx++) {
2577 alarm_free(btif_rc_cb.rc_multi_cb[idx].rc_play_status_timer);
2578 memset(&btif_rc_cb.rc_multi_cb[idx], 0, sizeof(btif_rc_cb.rc_multi_cb[idx]));
2579 }
2580
2581 memset(&btif_rc_cb.rc_multi_cb, 0, sizeof(btif_rc_cb.rc_multi_cb));
2582 log::verbose("completed");
2583 }
2584
2585 /***************************************************************************
2586 *
2587 * Function getcapabilities_cmd
2588 *
2589 * Description GetCapabilties from Remote(Company_ID, Events_Supported)
2590 *
2591 * Returns void
2592 *
2593 **************************************************************************/
getcapabilities_cmd(uint8_t cap_id,btif_rc_device_cb_t * p_dev)2594 static bt_status_t getcapabilities_cmd(uint8_t cap_id, btif_rc_device_cb_t* p_dev) {
2595 log::verbose("cap_id: {}", cap_id);
2596 CHECK_RC_CONNECTED(p_dev);
2597
2598 tAVRC_COMMAND avrc_cmd = {0};
2599 avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
2600 avrc_cmd.get_caps.capability_id = cap_id;
2601 avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
2602 avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
2603
2604 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2605 }
2606
2607 /***************************************************************************
2608 *
2609 * Function list_player_app_setting_attrib_cmd
2610 *
2611 * Description Get supported List Player Attributes
2612 *
2613 * Returns void
2614 *
2615 **************************************************************************/
list_player_app_setting_attrib_cmd(btif_rc_device_cb_t * p_dev)2616 static bt_status_t list_player_app_setting_attrib_cmd(btif_rc_device_cb_t* p_dev) {
2617 log::verbose("");
2618 CHECK_RC_CONNECTED(p_dev);
2619
2620 tAVRC_COMMAND avrc_cmd = {0};
2621 avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
2622 avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
2623 avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
2624
2625 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2626 }
2627
2628 /***************************************************************************
2629 *
2630 * Function list_player_app_setting_value_cmd
2631 *
2632 * Description Get values of supported Player Attributes
2633 *
2634 * Returns void
2635 *
2636 **************************************************************************/
list_player_app_setting_value_cmd(uint8_t attrib_id,btif_rc_device_cb_t * p_dev)2637 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id,
2638 btif_rc_device_cb_t* p_dev) {
2639 log::verbose("attrib_id: {}", attrib_id);
2640 CHECK_RC_CONNECTED(p_dev);
2641
2642 tAVRC_COMMAND avrc_cmd = {0};
2643 avrc_cmd.list_app_values.attr_id = attrib_id;
2644 avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
2645 avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
2646 avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
2647
2648 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2649 }
2650
2651 /***************************************************************************
2652 *
2653 * Function get_player_app_setting_cmd
2654 *
2655 * Description Get current values of Player Attributes
2656 *
2657 * Returns void
2658 *
2659 **************************************************************************/
get_player_app_setting_cmd(uint8_t num_attrib,uint8_t * attrib_ids,btif_rc_device_cb_t * p_dev)2660 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids,
2661 btif_rc_device_cb_t* p_dev) {
2662 log::verbose("num_attrib: {}", num_attrib);
2663 CHECK_RC_CONNECTED(p_dev);
2664
2665 tAVRC_COMMAND avrc_cmd = {0};
2666 avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
2667 avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
2668 avrc_cmd.get_cur_app_val.num_attr = num_attrib;
2669 avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
2670
2671 for (int count = 0; count < num_attrib; count++) {
2672 avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
2673 }
2674
2675 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
2676 }
2677
2678 /***************************************************************************
2679 *
2680 * Function get_current_metadata_cmd
2681 *
2682 * Description Fetch the current track metadata for the device
2683 *
2684 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2685 * BT_STATUS_FAIL.
2686 *
2687 **************************************************************************/
get_current_metadata_cmd(const RawAddress & bd_addr)2688 static bt_status_t get_current_metadata_cmd(const RawAddress& bd_addr) {
2689 log::verbose("");
2690 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2691 if (p_dev == NULL) {
2692 log::error("p_dev NULL");
2693 return BT_STATUS_DEVICE_NOT_FOUND;
2694 }
2695 const uint32_t* attr_list = get_requested_attributes_list(p_dev);
2696 const uint8_t attr_list_size = get_requested_attributes_list_size(p_dev);
2697 return get_metadata_attribute_cmd(attr_list_size, attr_list, p_dev);
2698 }
2699
2700 /***************************************************************************
2701 *
2702 * Function get_playback_state_cmd
2703 *
2704 * Description Fetch the current playback state for the device
2705 *
2706 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2707 * BT_STATUS_FAIL.
2708 *
2709 **************************************************************************/
get_playback_state_cmd(const RawAddress & bd_addr)2710 static bt_status_t get_playback_state_cmd(const RawAddress& bd_addr) {
2711 log::verbose("");
2712 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2713 return get_play_status_cmd(p_dev);
2714 }
2715
2716 /***************************************************************************
2717 *
2718 * Function get_now_playing_list_cmd
2719 *
2720 * Description Fetch the now playing list
2721 *
2722 * Paramters start_item: First item to fetch (0 to fetch from beganning)
2723 * end_item: Last item to fetch (0xffffffff to fetch until end)
2724 *
2725 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2726 * BT_STATUS_FAIL.
2727 *
2728 **************************************************************************/
get_now_playing_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2729 static bt_status_t get_now_playing_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2730 uint32_t end_item) {
2731 log::verbose("start, end: ({}, {})", start_item, end_item);
2732 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_NOW_PLAYING, start_item, end_item);
2733 }
2734
2735 /***************************************************************************
2736 *
2737 * Function get_item_attribute_cmd
2738 *
2739 * Description Fetch the item attributes for a given uid.
2740 *
2741 * Parameters uid: Track UID you want attributes for
2742 * scope: Constant representing which scope you're querying
2743 * (i.e AVRC_SCOPE_FILE_SYSTEM)
2744 * p_dev: Device control block
2745 *
2746 * Returns BT_STATUS_SUCCESS if command is issued successfully
2747 * otherwise BT_STATUS_FAIL
2748 *
2749 **************************************************************************/
get_item_attribute_cmd(uint64_t uid,int scope,uint8_t,const uint32_t *,btif_rc_device_cb_t * p_dev)2750 static bt_status_t get_item_attribute_cmd(uint64_t uid, int scope, uint8_t /*num_attribute*/,
2751 const uint32_t* /*p_attr_ids*/,
2752 btif_rc_device_cb_t* p_dev) {
2753 tAVRC_COMMAND avrc_cmd = {0};
2754 avrc_cmd.pdu = AVRC_PDU_GET_ITEM_ATTRIBUTES;
2755 avrc_cmd.get_attrs.scope = scope;
2756 memcpy(avrc_cmd.get_attrs.uid, &uid, 8);
2757 avrc_cmd.get_attrs.uid_counter = 0;
2758 avrc_cmd.get_attrs.attr_count = 0;
2759
2760 return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2761 }
2762
2763 /***************************************************************************
2764 *
2765 * Function get_folder_list_cmd
2766 *
2767 * Description Fetch the currently selected folder list
2768 *
2769 * Paramters start_item: First item to fetch (0 to fetch from beganning)
2770 * end_item: Last item to fetch (0xffffffff to fetch until end)
2771 *
2772 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2773 * BT_STATUS_FAIL.
2774 *
2775 **************************************************************************/
get_folder_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2776 static bt_status_t get_folder_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2777 uint32_t end_item) {
2778 log::verbose("start, end: ({}, {})", start_item, end_item);
2779 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_FILE_SYSTEM, start_item, end_item);
2780 }
2781
2782 /***************************************************************************
2783 *
2784 * Function get_player_list_cmd
2785 *
2786 * Description Fetch the player list
2787 *
2788 * Paramters start_item: First item to fetch (0 to fetch from beganning)
2789 * end_item: Last item to fetch (0xffffffff to fetch until end)
2790 *
2791 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2792 * BT_STATUS_FAIL.
2793 *
2794 **************************************************************************/
get_player_list_cmd(const RawAddress & bd_addr,uint32_t start_item,uint32_t end_item)2795 static bt_status_t get_player_list_cmd(const RawAddress& bd_addr, uint32_t start_item,
2796 uint32_t end_item) {
2797 log::verbose("start, end: ({}, {})", start_item, end_item);
2798 return get_folder_items_cmd(bd_addr, AVRC_SCOPE_PLAYER_LIST, start_item, end_item);
2799 }
2800
2801 /***************************************************************************
2802 *
2803 * Function change_folder_path_cmd
2804 *
2805 * Description Change the folder.
2806 *
2807 * Paramters direction: Direction (Up/Down) to change folder
2808 * uid: The UID of folder to move to
2809 * start_item: First item to fetch (0 to fetch from beganning)
2810 * end_item: Last item to fetch (0xffffffff to fetch until end)
2811 *
2812 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2813 * BT_STATUS_FAIL.
2814 *
2815 **************************************************************************/
change_folder_path_cmd(const RawAddress & bd_addr,uint8_t direction,uint8_t * uid)2816 static bt_status_t change_folder_path_cmd(const RawAddress& bd_addr, uint8_t direction,
2817 uint8_t* uid) {
2818 log::verbose("direction {}", direction);
2819 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2820 CHECK_RC_CONNECTED(p_dev);
2821 CHECK_BR_CONNECTED(p_dev);
2822
2823 tAVRC_COMMAND avrc_cmd = {0};
2824
2825 avrc_cmd.chg_path.pdu = AVRC_PDU_CHANGE_PATH;
2826 avrc_cmd.chg_path.status = AVRC_STS_NO_ERROR;
2827 // TODO(sanketa): Improve for database aware clients.
2828 avrc_cmd.chg_path.uid_counter = 0;
2829 avrc_cmd.chg_path.direction = direction;
2830
2831 memset(avrc_cmd.chg_path.folder_uid, 0, AVRC_UID_SIZE * sizeof(uint8_t));
2832 memcpy(avrc_cmd.chg_path.folder_uid, uid, AVRC_UID_SIZE * sizeof(uint8_t));
2833
2834 return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2835 }
2836
2837 /***************************************************************************
2838 *
2839 * Function set_browsed_player_cmd
2840 *
2841 * Description Change the browsed player.
2842 *
2843 * Paramters id: The UID of player to move to
2844 *
2845 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2846 * BT_STATUS_FAIL.
2847 *
2848 **************************************************************************/
set_browsed_player_cmd(const RawAddress & bd_addr,uint16_t id)2849 static bt_status_t set_browsed_player_cmd(const RawAddress& bd_addr, uint16_t id) {
2850 log::verbose("id {}", id);
2851 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2852 CHECK_RC_CONNECTED(p_dev);
2853 CHECK_BR_CONNECTED(p_dev);
2854
2855 tAVRC_COMMAND avrc_cmd = {0};
2856 avrc_cmd.br_player.pdu = AVRC_PDU_SET_BROWSED_PLAYER;
2857 avrc_cmd.br_player.status = AVRC_STS_NO_ERROR;
2858 // TODO(sanketa): Improve for database aware clients.
2859 avrc_cmd.br_player.player_id = id;
2860
2861 return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2862 }
2863
2864 /***************************************************************************
2865 **
2866 ** Function set_addressed_player_cmd
2867 **
2868 ** Description Change the addressed player.
2869 **
2870 ** Paramters id: The UID of player to move to
2871 **
2872 ** Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2873 ** BT_STATUS_FAIL.
2874 **
2875 ***************************************************************************/
set_addressed_player_cmd(const RawAddress & bd_addr,uint16_t id)2876 static bt_status_t set_addressed_player_cmd(const RawAddress& bd_addr, uint16_t id) {
2877 log::verbose("id {}", id);
2878
2879 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2880 CHECK_RC_CONNECTED(p_dev);
2881 CHECK_BR_CONNECTED(p_dev);
2882
2883 tAVRC_COMMAND avrc_cmd = {0};
2884 avrc_cmd.addr_player.pdu = AVRC_PDU_SET_ADDRESSED_PLAYER;
2885 avrc_cmd.addr_player.status = AVRC_STS_NO_ERROR;
2886 // TODO(sanketa): Improve for database aware clients.
2887 avrc_cmd.addr_player.player_id = id;
2888
2889 return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2890 }
2891
2892 /***************************************************************************
2893 *
2894 * Function get_folder_items_cmd
2895 *
2896 * Description Helper function to browse the content hierarchy of the
2897 * TG device.
2898 *
2899 * Paramters scope: AVRC_SCOPE_NOW_PLAYING (etc) for various browseable
2900 * content
2901 * start_item: First item to fetch (0 to fetch from beganning)
2902 * end_item: Last item to fetch (0xffff to fetch until end)
2903 *
2904 * Returns BT_STATUS_SUCCESS if command issued successfully otherwise
2905 * BT_STATUS_FAIL.
2906 *
2907 **************************************************************************/
get_folder_items_cmd(const RawAddress & bd_addr,uint8_t scope,uint32_t start_item,uint32_t end_item)2908 static bt_status_t get_folder_items_cmd(const RawAddress& bd_addr, uint8_t scope,
2909 uint32_t start_item, uint32_t end_item) {
2910 /* Check that both avrcp and browse channel are connected. */
2911 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2912 log::verbose("");
2913 CHECK_RC_CONNECTED(p_dev);
2914 CHECK_BR_CONNECTED(p_dev);
2915
2916 tAVRC_COMMAND avrc_cmd = {0};
2917
2918 /* Set the layer specific to point to browse although this should really
2919 * be done by lower layers and looking at the PDU
2920 */
2921 avrc_cmd.get_items.pdu = AVRC_PDU_GET_FOLDER_ITEMS;
2922 avrc_cmd.get_items.status = AVRC_STS_NO_ERROR;
2923 avrc_cmd.get_items.scope = scope;
2924 avrc_cmd.get_items.start_item = start_item;
2925 avrc_cmd.get_items.end_item = end_item;
2926 avrc_cmd.get_items.attr_count = 0; /* p_attr_list does not matter hence */
2927
2928 return build_and_send_browsing_cmd(&avrc_cmd, p_dev);
2929 }
2930
2931 /***************************************************************************
2932 *
2933 * Function change_player_app_setting
2934 *
2935 * Description Set current values of Player Attributes
2936 *
2937 * Returns void
2938 *
2939 **************************************************************************/
change_player_app_setting(const RawAddress & bd_addr,uint8_t num_attrib,uint8_t * attrib_ids,uint8_t * attrib_vals)2940 static bt_status_t change_player_app_setting(const RawAddress& bd_addr, uint8_t num_attrib,
2941 uint8_t* attrib_ids, uint8_t* attrib_vals) {
2942 log::verbose("num_attrib: {}", num_attrib);
2943 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2944 CHECK_RC_CONNECTED(p_dev);
2945
2946 tAVRC_COMMAND avrc_cmd = {0};
2947 avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
2948 avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
2949 avrc_cmd.set_app_val.num_val = num_attrib;
2950 avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
2951 avrc_cmd.set_app_val.p_vals =
2952 (tAVRC_APP_SETTING*)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
2953 for (int count = 0; count < num_attrib; count++) {
2954 avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
2955 avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
2956 }
2957
2958 bt_status_t st = build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
2959 osi_free_and_reset((void**)&avrc_cmd.set_app_val.p_vals);
2960 return st;
2961 }
2962
2963 /***************************************************************************
2964 *
2965 * Function play_item_cmd
2966 *
2967 * Description Play the item specified by UID & scope
2968 *
2969 * Returns void
2970 *
2971 **************************************************************************/
play_item_cmd(const RawAddress & bd_addr,uint8_t scope,uint8_t * uid,uint16_t uid_counter)2972 static bt_status_t play_item_cmd(const RawAddress& bd_addr, uint8_t scope, uint8_t* uid,
2973 uint16_t uid_counter) {
2974 log::verbose("scope {} uid_counter {}", scope, uid_counter);
2975 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
2976 CHECK_RC_CONNECTED(p_dev);
2977 CHECK_BR_CONNECTED(p_dev);
2978
2979 tAVRC_COMMAND avrc_cmd = {0};
2980 avrc_cmd.pdu = AVRC_PDU_PLAY_ITEM;
2981 avrc_cmd.play_item.opcode = AVRC_OP_VENDOR;
2982 avrc_cmd.play_item.status = AVRC_STS_NO_ERROR;
2983 avrc_cmd.play_item.scope = scope;
2984 memcpy(avrc_cmd.play_item.uid, uid, AVRC_UID_SIZE);
2985 avrc_cmd.play_item.uid_counter = uid_counter;
2986
2987 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_CTRL, p_dev);
2988 }
2989
2990 /***************************************************************************
2991 *
2992 * Function get_player_app_setting_attr_text_cmd
2993 *
2994 * Description Get text description for app attribute
2995 *
2996 * Returns void
2997 *
2998 **************************************************************************/
get_player_app_setting_attr_text_cmd(uint8_t * attrs,uint8_t num_attrs,btif_rc_device_cb_t * p_dev)2999 static bt_status_t get_player_app_setting_attr_text_cmd(uint8_t* attrs, uint8_t num_attrs,
3000 btif_rc_device_cb_t* p_dev) {
3001 log::verbose("num attrs: {}", num_attrs);
3002 CHECK_RC_CONNECTED(p_dev);
3003
3004 tAVRC_COMMAND avrc_cmd = {0};
3005 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3006 avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3007 avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3008
3009 for (int count = 0; count < num_attrs; count++) {
3010 avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3011 }
3012
3013 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3014 }
3015
3016 /***************************************************************************
3017 *
3018 * Function get_player_app_setting_val_text_cmd
3019 *
3020 * Description Get text description for app attribute values
3021 *
3022 * Returns void
3023 *
3024 **************************************************************************/
get_player_app_setting_value_text_cmd(uint8_t * vals,uint8_t num_vals,btif_rc_device_cb_t * p_dev)3025 static bt_status_t get_player_app_setting_value_text_cmd(uint8_t* vals, uint8_t num_vals,
3026 btif_rc_device_cb_t* p_dev) {
3027 log::verbose("num_vals: {}", num_vals);
3028 CHECK_RC_CONNECTED(p_dev);
3029
3030 tAVRC_COMMAND avrc_cmd = {0};
3031 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3032 avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3033 avrc_cmd.get_app_val_txt.num_val = num_vals;
3034
3035 for (int count = 0; count < num_vals; count++) {
3036 avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3037 }
3038
3039 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3040 }
3041
3042 /***************************************************************************
3043 *
3044 * Function register_notification_cmd
3045 *
3046 * Description Send Command to register for a Notification ID
3047 *
3048 * Returns void
3049 *
3050 **************************************************************************/
register_notification_cmd(uint8_t event_id,uint32_t event_value,btif_rc_device_cb_t * p_dev)3051 static bt_status_t register_notification_cmd(uint8_t event_id, uint32_t event_value,
3052 btif_rc_device_cb_t* p_dev) {
3053 log::verbose("event_id: {} event_value {}", event_id, event_value);
3054 CHECK_RC_CONNECTED(p_dev);
3055
3056 tAVRC_COMMAND avrc_cmd = {0};
3057 avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3058 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3059 avrc_cmd.reg_notif.event_id = event_id;
3060 avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3061 avrc_cmd.reg_notif.param = event_value;
3062
3063 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_NOTIF, p_dev);
3064 }
3065
3066 /***************************************************************************
3067 *
3068 * Function get_metadata_attribute_cmd
3069 *
3070 * Description Get metadata attributes for attributeIds. This function
3071 * will make the right determination of whether to use the
3072 * control or browsing channel for the request
3073 *
3074 * Returns BT_STATUS_SUCCESS if the command is successfully issued
3075 * otherwise BT_STATUS_FAIL
3076 *
3077 **************************************************************************/
get_metadata_attribute_cmd(uint8_t num_attribute,const uint32_t * p_attr_ids,btif_rc_device_cb_t * p_dev)3078 static bt_status_t get_metadata_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
3079 btif_rc_device_cb_t* p_dev) {
3080 log::verbose("num_attribute: {} attribute_id: {}", num_attribute, p_attr_ids[0]);
3081
3082 // If browsing is connected then send the command out that channel
3083 if (p_dev->br_connected) {
3084 return get_item_attribute_cmd(p_dev->rc_playing_uid, AVRC_SCOPE_NOW_PLAYING, num_attribute,
3085 p_attr_ids, p_dev);
3086 }
3087
3088 // Otherwise, default to the control channel
3089 return get_element_attribute_cmd(num_attribute, p_attr_ids, p_dev);
3090 }
3091
3092 /***************************************************************************
3093 *
3094 * Function get_element_attribute_cmd
3095 *
3096 * Description Get Element Attribute for attributeIds
3097 *
3098 * Returns void
3099 *
3100 **************************************************************************/
get_element_attribute_cmd(uint8_t num_attribute,const uint32_t * p_attr_ids,btif_rc_device_cb_t * p_dev)3101 static bt_status_t get_element_attribute_cmd(uint8_t num_attribute, const uint32_t* p_attr_ids,
3102 btif_rc_device_cb_t* p_dev) {
3103 log::verbose("num_attribute: {} attribute_id: {}", num_attribute, p_attr_ids[0]);
3104 CHECK_RC_CONNECTED(p_dev);
3105 tAVRC_COMMAND avrc_cmd = {0};
3106 avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3107 avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3108 avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3109 avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3110 for (int count = 0; count < num_attribute; count++) {
3111 avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3112 }
3113
3114 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3115 }
3116
3117 /***************************************************************************
3118 *
3119 * Function get_play_status_cmd
3120 *
3121 * Description Get Playing Status of a Device
3122 *
3123 * Returns bt_status_t
3124 *
3125 **************************************************************************/
get_play_status_cmd(btif_rc_device_cb_t * p_dev)3126 static bt_status_t get_play_status_cmd(btif_rc_device_cb_t* p_dev) {
3127 log::verbose("");
3128 CHECK_RC_CONNECTED(p_dev);
3129
3130 tAVRC_COMMAND avrc_cmd = {0};
3131 avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3132 avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3133 avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3134
3135 return build_and_send_vendor_cmd(&avrc_cmd, AVRC_CMD_STATUS, p_dev);
3136 }
3137
3138 /***************************************************************************
3139 *
3140 * Function set_volume_rsp
3141 *
3142 * Description Rsp for SetAbsoluteVolume Command
3143 *
3144 * Returns void
3145 *
3146 **************************************************************************/
set_volume_rsp(const RawAddress & bd_addr,uint8_t abs_vol,uint8_t label)3147 static bt_status_t set_volume_rsp(const RawAddress& bd_addr, uint8_t abs_vol, uint8_t label) {
3148 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3149 tAVRC_RESPONSE avrc_rsp;
3150 BT_HDR* p_msg = NULL;
3151 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3152
3153 CHECK_RC_CONNECTED(p_dev);
3154
3155 log::verbose("abs_vol: {}", abs_vol);
3156
3157 avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3158 avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3159 avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3160 avrc_rsp.volume.volume = abs_vol;
3161 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
3162 if (status == AVRC_STS_NO_ERROR) {
3163 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
3164 log::verbose("msgreq being sent out with label: {}", p_dev->rc_vol_label);
3165 if (p_msg != NULL) {
3166 BTA_AvVendorRsp(p_dev->rc_handle, label, AVRC_RSP_ACCEPT, data_start, p_msg->len, 0);
3167 status = BT_STATUS_SUCCESS;
3168 }
3169 } else {
3170 log::error("failed to build command. status: 0x{:02x}", status);
3171 }
3172 osi_free(p_msg);
3173 return (bt_status_t)status;
3174 }
3175
3176 /***************************************************************************
3177 *
3178 * Function send_register_abs_vol_rsp
3179 *
3180 * Description Rsp for Notification of Absolute Volume
3181 *
3182 * Returns void
3183 *
3184 **************************************************************************/
volume_change_notification_rsp(const RawAddress & bd_addr,btrc_notification_type_t rsp_type,uint8_t abs_vol,uint8_t label)3185 static bt_status_t volume_change_notification_rsp(const RawAddress& bd_addr,
3186 btrc_notification_type_t rsp_type,
3187 uint8_t abs_vol, uint8_t label) {
3188 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3189 tAVRC_RESPONSE avrc_rsp;
3190 BT_HDR* p_msg = NULL;
3191 log::verbose("rsp_type: {} abs_vol: {}", rsp_type, abs_vol);
3192
3193 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3194
3195 CHECK_RC_CONNECTED(p_dev);
3196
3197 avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3198 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3199 avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3200 avrc_rsp.reg_notif.param.volume = abs_vol;
3201 avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3202
3203 status = AVRC_BldResponse(p_dev->rc_handle, &avrc_rsp, &p_msg);
3204 if (status == AVRC_STS_NO_ERROR) {
3205 log::verbose("msgreq being sent out with label: {}", label);
3206 uint8_t* data_start = (uint8_t*)(p_msg + 1) + p_msg->offset;
3207 BTA_AvVendorRsp(
3208 p_dev->rc_handle, label,
3209 (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ? AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3210 data_start, p_msg->len, 0);
3211 status = BT_STATUS_SUCCESS;
3212 } else {
3213 log::error("failed to build command. status: 0x{:02x}", status);
3214 }
3215 osi_free(p_msg);
3216
3217 return (bt_status_t)status;
3218 }
3219
3220 /***************************************************************************
3221 *
3222 * Function send_groupnavigation_cmd
3223 *
3224 * Description Send Pass-Through command
3225 *
3226 * Returns void
3227 *
3228 **************************************************************************/
send_groupnavigation_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)3229 static bt_status_t send_groupnavigation_cmd(const RawAddress& bd_addr, uint8_t key_code,
3230 uint8_t key_state) {
3231 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3232 rc_transaction_t* p_transaction = NULL;
3233 log::verbose("key-code: {}, key-state: {}", key_code, key_state);
3234 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(bd_addr);
3235
3236 CHECK_RC_CONNECTED(p_dev);
3237
3238 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
3239 rc_transaction_context_t context = {
3240 .rc_addr = p_dev->rc_addr,
3241 .label = MAX_LABEL,
3242 .opcode = AVRC_OP_PASS_THRU,
3243 .command = {.passthru = {AVRC_ID_VENDOR, key_state, key_code}}};
3244 bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
3245 if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3246 uint8_t buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3247 uint8_t* start = buffer;
3248 UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3249 *(start)++ = 0;
3250 UINT8_TO_BE_STREAM(start, key_code);
3251 BTA_AvRemoteVendorUniqueCmd(p_dev->rc_handle, p_transaction->label, (tBTA_AV_STATE)key_state,
3252 buffer, AVRC_PASS_THRU_GROUP_LEN);
3253 status = BT_STATUS_SUCCESS;
3254 start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
3255 log::verbose("Send command, key-code={}, key-state={}, label={}", key_code, key_state,
3256 p_transaction->label);
3257 } else {
3258 status = BT_STATUS_FAIL;
3259 log::error("failed to get label, key-code={}, key-state={}, status={}", key_code, key_state,
3260 tran_status);
3261 }
3262 } else {
3263 status = BT_STATUS_UNSUPPORTED;
3264 log::verbose("feature not supported");
3265 }
3266 return (bt_status_t)status;
3267 }
3268
3269 /***************************************************************************
3270 *
3271 * Function send_passthrough_cmd
3272 *
3273 * Description Send Pass-Through command
3274 *
3275 * Returns void
3276 *
3277 **************************************************************************/
send_passthrough_cmd(const RawAddress & bd_addr,uint8_t key_code,uint8_t key_state)3278 static bt_status_t send_passthrough_cmd(const RawAddress& bd_addr, uint8_t key_code,
3279 uint8_t key_state) {
3280 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3281 btif_rc_device_cb_t* p_dev = NULL;
3282 log::error("calling btif_rc_get_device_by_bda");
3283 p_dev = btif_rc_get_device_by_bda(bd_addr);
3284
3285 CHECK_RC_CONNECTED(p_dev);
3286
3287 rc_transaction_t* p_transaction = NULL;
3288 log::verbose("key-code: {}, key-state: {}", key_code, key_state);
3289 if (p_dev->rc_features & BTA_AV_FEAT_RCTG) {
3290 rc_transaction_context_t context = {
3291 .rc_addr = p_dev->rc_addr,
3292 .label = MAX_LABEL,
3293 .opcode = AVRC_OP_PASS_THRU,
3294 .command = {.passthru = {AVRC_ID_VENDOR, key_state, key_code}}};
3295 bt_status_t tran_status = get_transaction(p_dev, context, &p_transaction);
3296 if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction) {
3297 BTA_AvRemoteCmd(p_dev->rc_handle, p_transaction->label, (tBTA_AV_RC)key_code,
3298 (tBTA_AV_STATE)key_state);
3299 status = BT_STATUS_SUCCESS;
3300 start_transaction_timer(p_dev, p_transaction->label, BTIF_RC_TIMEOUT_MS);
3301 log::verbose("Send command, key-code={}, key-state={}, label={}", key_code, key_state,
3302 p_transaction->label);
3303 } else {
3304 status = BT_STATUS_FAIL;
3305 log::error("failed to get label, key-code={}, key-state={}, status={}", key_code, key_state,
3306 tran_status);
3307 }
3308 } else {
3309 status = BT_STATUS_UNSUPPORTED;
3310 log::verbose("feature not supported");
3311 }
3312 return (bt_status_t)status;
3313 }
3314
3315 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
3316 sizeof(bt_rc_ctrl_interface),
3317 init_ctrl,
3318 send_passthrough_cmd,
3319 send_groupnavigation_cmd,
3320 change_player_app_setting,
3321 play_item_cmd,
3322 get_current_metadata_cmd,
3323 get_playback_state_cmd,
3324 get_now_playing_list_cmd,
3325 get_folder_list_cmd,
3326 get_player_list_cmd,
3327 change_folder_path_cmd,
3328 set_browsed_player_cmd,
3329 set_addressed_player_cmd,
3330 set_volume_rsp,
3331 volume_change_notification_rsp,
3332 cleanup_ctrl,
3333 };
3334
3335 /*******************************************************************************
3336 *
3337 * Function btif_rc_ctrl_get_interface
3338 *
3339 * Description Get the AVRCP Controller callback interface
3340 *
3341 * Returns btrc_ctrl_interface_t
3342 *
3343 ******************************************************************************/
btif_rc_ctrl_get_interface(void)3344 const btrc_ctrl_interface_t* btif_rc_ctrl_get_interface(void) { return &bt_rc_ctrl_interface; }
3345
3346 /*******************************************************************************
3347 * Function initialize_transaction
3348 *
3349 * Description Initializes fields of the transaction structure
3350 *
3351 * Returns void
3352 ******************************************************************************/
initialize_transaction(btif_rc_device_cb_t * p_dev,uint8_t lbl)3353 static void initialize_transaction(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3354 if (p_dev == nullptr) {
3355 return;
3356 }
3357 rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3358 std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3359 if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
3360 log::verbose("initialize transaction, dev={}, label={}", p_dev->rc_addr, lbl);
3361 if (alarm_is_scheduled(transaction_set->transaction[lbl].timer)) {
3362 log::warn("clearing pending timer event, dev={}, label={}", p_dev->rc_addr, lbl);
3363 clear_cmd_timeout(p_dev, lbl);
3364 }
3365 transaction_set->transaction[lbl] = {
3366 .in_use = false,
3367 .label = lbl,
3368 .context =
3369 {
3370 .rc_addr = RawAddress::kEmpty,
3371 .label = MAX_LABEL,
3372 .opcode = AVRC_OP_INVALID,
3373 .command = {},
3374 },
3375 .timer = nullptr,
3376 };
3377 }
3378 }
3379
3380 /*******************************************************************************
3381 *
3382 * Function init_all_transactions
3383 *
3384 * Description Initializes all transactions
3385 *
3386 * Returns void
3387 ******************************************************************************/
init_all_transactions(btif_rc_device_cb_t * p_dev)3388 void init_all_transactions(btif_rc_device_cb_t* p_dev) {
3389 if (p_dev == nullptr) {
3390 return;
3391 }
3392 for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; ++i) {
3393 initialize_transaction(p_dev, i);
3394 }
3395 }
3396
3397 /*******************************************************************************
3398 *
3399 * Function get_transaction_by_lbl
3400 *
3401 * Description Will return a transaction based on the label. If not inuse
3402 * will return an error.
3403 *
3404 * Returns bt_status_t
3405 ******************************************************************************/
get_transaction_by_lbl(btif_rc_device_cb_t * p_dev,uint8_t lbl)3406 rc_transaction_t* get_transaction_by_lbl(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3407 if (p_dev == nullptr) {
3408 return nullptr;
3409 }
3410
3411 rc_transaction_t* transaction = NULL;
3412 rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3413 std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3414
3415 /* Determine if this is a valid label */
3416 if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
3417 if (!transaction_set->transaction[lbl].in_use) {
3418 transaction = NULL;
3419 } else {
3420 transaction = &(transaction_set->transaction[lbl]);
3421 }
3422 }
3423 return transaction;
3424 }
3425
3426 /*******************************************************************************
3427 *
3428 * Function get_transaction
3429 *
3430 * Description Obtains the transaction details.
3431 *
3432 * Returns bt_status_t
3433 ******************************************************************************/
get_transaction(btif_rc_device_cb_t * p_dev,rc_transaction_context_t & context,rc_transaction_t ** ptransaction)3434 static bt_status_t get_transaction(btif_rc_device_cb_t* p_dev, rc_transaction_context_t& context,
3435 rc_transaction_t** ptransaction) {
3436 if (p_dev == NULL) {
3437 return BT_STATUS_PARM_INVALID;
3438 }
3439 rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3440 std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3441
3442 // Check for unused transactions in the device's transaction set
3443 for (uint8_t i = 0; i < MAX_TRANSACTIONS_PER_SESSION; i++) {
3444 if (!transaction_set->transaction[i].in_use) {
3445 context.label = i;
3446 transaction_set->transaction[i].context = context;
3447 transaction_set->transaction[i].in_use = true;
3448 *ptransaction = &(transaction_set->transaction[i]);
3449 log::verbose("Assigned transaction, dev={}, transaction={}", p_dev->rc_addr,
3450 dump_transaction(*ptransaction));
3451 return BT_STATUS_SUCCESS;
3452 }
3453 }
3454 log::error("p_dev={}, failed to find free transaction", p_dev->rc_addr);
3455 return BT_STATUS_NOMEM;
3456 }
3457
3458 /*******************************************************************************
3459 *
3460 * Function start_transaction_timer
3461 *
3462 * Description Starts a timer to release the label in case we don't get a
3463 * response. Uses the central timeout handler, which will route
3464 * timeout events based on context opcode and pdu_id
3465 *
3466 * Returns void
3467 ******************************************************************************/
start_transaction_timer(btif_rc_device_cb_t * p_dev,uint8_t label,uint64_t timeout_ms)3468 static void start_transaction_timer(btif_rc_device_cb_t* p_dev, uint8_t label,
3469 uint64_t timeout_ms) {
3470 rc_transaction_t* transaction = get_transaction_by_lbl(p_dev, label);
3471 if (transaction == nullptr) {
3472 log::error("transaction is null");
3473 return;
3474 }
3475
3476 if (alarm_is_scheduled(transaction->timer)) {
3477 log::warn("Restarting timer that's already scheduled");
3478 }
3479
3480 std::stringstream ss;
3481 ss << "btif_rc." << p_dev->rc_addr.ToColonSepHexString() << "." << transaction->label;
3482 alarm_free(transaction->timer);
3483 transaction->timer = alarm_new(ss.str().c_str());
3484 alarm_set_on_mloop(transaction->timer, timeout_ms, btif_rc_transaction_timer_timeout,
3485 &transaction->context);
3486 }
3487
3488 /*******************************************************************************
3489 *
3490 * Function release_transaction
3491 *
3492 * Description Will release a transaction for reuse
3493 *
3494 * Returns bt_status_t
3495 ******************************************************************************/
release_transaction(btif_rc_device_cb_t * p_dev,uint8_t lbl)3496 void release_transaction(btif_rc_device_cb_t* p_dev, uint8_t lbl) {
3497 if (p_dev == nullptr) {
3498 log::warn("Failed to release transaction, dev=null, label={}", lbl);
3499 return;
3500 }
3501 rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3502 std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3503
3504 rc_transaction_t* transaction = get_transaction_by_lbl(p_dev, lbl);
3505
3506 /* If the transaction is in use... */
3507 if (transaction != NULL) {
3508 log::verbose("Released transaction, dev={}, label={}", p_dev->rc_addr, lbl);
3509 initialize_transaction(p_dev, lbl);
3510 } else {
3511 log::warn("Failed to release transaction, could not find dev={}, label={}", p_dev->rc_addr,
3512 lbl);
3513 }
3514 }
3515
3516 /*******************************************************************************
3517 *
3518 * Function dump_transaction
3519 *
3520 * Description Dump transactions info for debugging
3521 *
3522 * Returns String of transaction info
3523 ******************************************************************************/
dump_transaction(const rc_transaction_t * const transaction)3524 static std::string dump_transaction(const rc_transaction_t* const transaction) {
3525 std::stringstream ss;
3526
3527 ss << "label=" << (int)transaction->label;
3528 ss << " in_use=" << (transaction->in_use ? "true" : "false");
3529
3530 rc_transaction_context_t context = transaction->context;
3531 ss << " context=(";
3532 uint8_t opcode_id = context.opcode;
3533 ss << "opcode=" << dump_rc_opcode(opcode_id);
3534 switch (opcode_id) {
3535 case AVRC_OP_VENDOR:
3536 ss << " pdu_id=" << dump_rc_pdu(context.command.vendor.pdu_id);
3537 if (context.command.vendor.pdu_id == AVRC_PDU_REGISTER_NOTIFICATION) {
3538 ss << " event_id=" << dump_rc_notification_event_id(context.command.vendor.event_id);
3539 }
3540 break;
3541 case AVRC_OP_BROWSE:
3542 ss << " pdu_id=" << dump_rc_pdu(context.command.browse.pdu_id);
3543 break;
3544 case AVRC_OP_PASS_THRU:
3545 ss << " rc_id=" << context.command.passthru.rc_id;
3546 ss << " key_state=" << context.command.passthru.key_state;
3547 break;
3548 }
3549 ss << ")";
3550
3551 ss << " alarm=";
3552 alarm_t* alarm = transaction->timer;
3553 if (alarm != nullptr) {
3554 ss << "(set=" << alarm_is_scheduled(alarm) << " left=" << alarm_get_remaining_ms(alarm) << ")";
3555 } else {
3556 ss << "null";
3557 }
3558 return ss.str();
3559 }
3560
3561 /***************************************************************************
3562 *
3563 * Function vendor_cmd_timeout_handler
3564 *
3565 * Description vendor dependent command timeout handler
3566 * Returns None
3567 *
3568 **************************************************************************/
vendor_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_vendor_context_t * p_context)3569 static void vendor_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3570 rc_vendor_context_t* p_context) {
3571 if (p_dev == NULL) {
3572 log::error("p_dev NULL");
3573 return;
3574 }
3575
3576 tAVRC_RESPONSE avrc_response = {0};
3577 tBTA_AV_META_MSG meta_msg = {.rc_handle = p_dev->rc_handle};
3578
3579 log::warn("timeout, addr={}, label={}, pdu_id={}, event_id={}", p_dev->rc_addr, label,
3580 dump_rc_pdu(p_context->pdu_id), dump_rc_notification_event_id(p_context->event_id));
3581
3582 switch (p_context->pdu_id) {
3583 case AVRC_PDU_REGISTER_NOTIFICATION:
3584 rc_notification_interim_timeout(p_dev, p_context->event_id);
3585 break;
3586
3587 case AVRC_PDU_GET_CAPABILITIES:
3588 avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
3589 handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
3590 break;
3591
3592 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3593 avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
3594 handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
3595 break;
3596
3597 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3598 avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
3599 handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
3600 break;
3601
3602 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3603 avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
3604 handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
3605 break;
3606
3607 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3608 avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
3609 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
3610 break;
3611
3612 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3613 avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
3614 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
3615 break;
3616
3617 case AVRC_PDU_GET_ELEMENT_ATTR:
3618 avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT;
3619 handle_get_metadata_attr_response(&meta_msg, &avrc_response.get_attrs);
3620 break;
3621
3622 case AVRC_PDU_GET_PLAY_STATUS:
3623 avrc_response.get_play_status.status = BTIF_RC_STS_TIMEOUT;
3624 handle_get_playstatus_response(&meta_msg, &avrc_response.get_play_status);
3625 break;
3626
3627 case AVRC_PDU_SET_PLAYER_APP_VALUE:
3628 avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
3629 handle_set_app_attr_val_response(&meta_msg, &avrc_response.set_app_val);
3630 break;
3631
3632 case AVRC_PDU_PLAY_ITEM:
3633 // Nothing to notify on, just release the label
3634 break;
3635
3636 default:
3637 log::warn("timeout for unknown pdu_id={}", p_context->pdu_id);
3638 break;
3639 }
3640 }
3641
3642 /***************************************************************************
3643 *
3644 * Function browse_cmd_timeout_handler
3645 *
3646 * Description Browse command timeout handler
3647 * Returns None
3648 *
3649 **************************************************************************/
browse_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_browse_context_t * p_context)3650 static void browse_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3651 rc_browse_context_t* p_context) {
3652 if (p_dev == NULL) {
3653 log::error("p_dev NULL");
3654 return;
3655 }
3656
3657 tAVRC_RESPONSE avrc_response = {0};
3658 tBTA_AV_META_MSG meta_msg = {
3659 .rc_handle = p_dev->rc_handle,
3660 .len = 0,
3661 .label = 0,
3662 .code = 0,
3663 .company_id = 0,
3664 .p_data = nullptr,
3665 .p_msg = nullptr,
3666 };
3667
3668 log::warn("timeout, addr={}, label={}, pdu_id={}", p_dev->rc_addr, label,
3669 dump_rc_pdu(p_context->pdu_id));
3670
3671 switch (p_context->pdu_id) {
3672 case AVRC_PDU_GET_FOLDER_ITEMS:
3673 avrc_response.get_items.status = BTIF_RC_STS_TIMEOUT;
3674 handle_get_folder_items_response(&meta_msg, &avrc_response.get_items);
3675 break;
3676 case AVRC_PDU_CHANGE_PATH:
3677 avrc_response.chg_path.status = BTIF_RC_STS_TIMEOUT;
3678 handle_change_path_response(&meta_msg, &avrc_response.chg_path);
3679 break;
3680 case AVRC_PDU_SET_BROWSED_PLAYER:
3681 avrc_response.br_player.status = BTIF_RC_STS_TIMEOUT;
3682 handle_set_browsed_player_response(&meta_msg, &avrc_response.br_player);
3683 break;
3684 case AVRC_PDU_GET_ITEM_ATTRIBUTES:
3685 avrc_response.get_attrs.status = BTIF_RC_STS_TIMEOUT;
3686 handle_get_metadata_attr_response(&meta_msg, &avrc_response.get_attrs);
3687 break;
3688 default:
3689 log::warn("timeout for unknown pdu_id={}", p_context->pdu_id);
3690 break;
3691 }
3692 }
3693
3694 /***************************************************************************
3695 *
3696 * Function passthru_cmd_timeout_handler
3697 *
3698 * Description Pass-thru command timeout handler
3699 * Returns None
3700 *
3701 **************************************************************************/
passthru_cmd_timeout_handler(btif_rc_device_cb_t * p_dev,uint8_t label,rc_passthru_context_t * p_context)3702 static void passthru_cmd_timeout_handler(btif_rc_device_cb_t* p_dev, uint8_t label,
3703 rc_passthru_context_t* p_context) {
3704 if (p_dev == NULL) {
3705 log::error("p_dev NULL");
3706 return;
3707 }
3708
3709 log::warn("timeout, addr={}, label={}, rc_id={}, key_state={}", p_dev->rc_addr, label,
3710 p_context->rc_id, p_context->key_state);
3711
3712 // Other requests are wrapped in a tAVRC_RESPONSE response object, but these
3713 // passthru events are not in there. As well, the upper layers don't handle
3714 // these events anyways. If that were to change, we could check the rc_id and
3715 // choose to route either the passthrough handler or vendorunique handler here
3716 return;
3717 }
3718
3719 /***************************************************************************
3720 *
3721 * Function btif_rc_transaction_timeout_handler
3722 *
3723 * Description RC transaction timeout handler (Runs in BTIF context).
3724 * Returns None
3725 *
3726 **************************************************************************/
btif_rc_transaction_timeout_handler(uint16_t,char * data)3727 static void btif_rc_transaction_timeout_handler(uint16_t /* event */, char* data) {
3728 rc_transaction_context_t* p_context = (rc_transaction_context_t*)data;
3729 if (p_context == nullptr) {
3730 log::error("p_context is null");
3731 return;
3732 }
3733
3734 btif_rc_device_cb_t* p_dev = btif_rc_get_device_by_bda(p_context->rc_addr);
3735 if (p_dev == NULL) {
3736 log::error("p_dev is null");
3737 return;
3738 }
3739
3740 uint8_t label = p_context->label;
3741 switch (p_context->opcode) {
3742 case AVRC_OP_VENDOR:
3743 vendor_cmd_timeout_handler(p_dev, label, &(p_context->command.vendor));
3744 break;
3745 case AVRC_OP_BROWSE:
3746 browse_cmd_timeout_handler(p_dev, label, &(p_context->command.browse));
3747 break;
3748 case AVRC_OP_PASS_THRU:
3749 passthru_cmd_timeout_handler(p_dev, label, &(p_context->command.passthru));
3750 break;
3751 default:
3752 log::warn("received timeout for unknown opcode={}", p_context->opcode);
3753 return;
3754 }
3755 release_transaction(p_dev, label);
3756 }
3757
3758 /***************************************************************************
3759 *
3760 * Function btif_rc_transaction_timer_timeout
3761 *
3762 * Description RC transaction timeout callback.
3763 * This is called from BTU context and switches to BTIF
3764 * context to handle the timeout events
3765 * Returns None
3766 *
3767 **************************************************************************/
btif_rc_transaction_timer_timeout(void * data)3768 static void btif_rc_transaction_timer_timeout(void* data) {
3769 rc_transaction_context_t* p_data = (rc_transaction_context_t*)data;
3770
3771 btif_transfer_context(btif_rc_transaction_timeout_handler, 0, (char*)p_data,
3772 sizeof(rc_transaction_context_t), NULL);
3773 }
3774
3775 /*******************************************************************************
3776 * Function btif_debug_rc_dump
3777 *
3778 * Description Dumps the state of the btif_rc subsytem
3779 *
3780 * Returns void
3781 ******************************************************************************/
btif_debug_rc_dump(int fd)3782 void btif_debug_rc_dump(int fd) {
3783 dprintf(fd, "\nAVRCP Native State:\n");
3784
3785 int connected_count = 0;
3786 for (int i = 0; i < BTIF_RC_NUM_CONN; ++i) {
3787 const btrc_connection_state_t state = btif_rc_cb.rc_multi_cb[i].rc_state;
3788 if (state != BTRC_CONNECTION_STATE_DISCONNECTED) {
3789 ++connected_count;
3790 }
3791 }
3792
3793 dprintf(fd, " Devices (%d / %d):\n", connected_count, BTIF_RC_NUM_CONN - 1);
3794 for (int i = 0; i < BTIF_RC_NUM_CONN; ++i) {
3795 btif_rc_device_cb_t* p_dev = &btif_rc_cb.rc_multi_cb[i];
3796 if (p_dev->rc_state != BTRC_CONNECTION_STATE_DISCONNECTED) {
3797 dprintf(fd, " %s:\n", p_dev->rc_addr.ToRedactedStringForLogging().c_str());
3798
3799 rc_transaction_set_t* transaction_set = &(p_dev->transaction_set);
3800 std::unique_lock<std::recursive_mutex> lock(transaction_set->label_lock);
3801 dprintf(fd, " Transaction Labels:\n");
3802 for (auto j = 0; j < MAX_TRANSACTIONS_PER_SESSION; ++j) {
3803 dprintf(fd, " %s\n", dump_transaction(&transaction_set->transaction[j]).c_str());
3804 }
3805 }
3806 }
3807 }
3808