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