2 * Copyright (C) 2015 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 /*****************************************************************************
21 * Description: Bluetooth AVRC implementation
23 *****************************************************************************/
25 #define LOG_TAG "bt_btif_avrc"
34 #include <hardware/bluetooth.h>
35 #include <hardware/bt_rc.h>
38 * TODO(eisenbach): cutils/properties.h is only being used to pull-in runtime
39 * settings on Android. Remove this conditional include once we have a generic
40 * way to obtain system properties.
42 #if !defined(OS_GENERIC)
43 #include <cutils/properties.h>
44 #endif /* !defined(OS_GENERIC) */
46 #include "avrc_defs.h"
48 #include "bta_av_api.h"
50 #include "btif_common.h"
51 #include "btif_util.h"
52 #include "bt_common.h"
53 #include "device/include/interop.h"
55 #include "osi/include/list.h"
57 #define RC_INVALID_TRACK_ID (0xFFFFFFFFFFFFFFFFULL)
58 /*****************************************************************************
60 ******************************************************************************/
62 /* cod value for Headsets */
63 #define COD_AV_HEADSETS 0x0404
64 /* for AVRC 1.4 need to change this */
65 #define MAX_RC_NOTIFICATIONS AVRC_EVT_VOLUME_CHANGE
67 #define IDX_GET_PLAY_STATUS_RSP 0
68 #define IDX_LIST_APP_ATTR_RSP 1
69 #define IDX_LIST_APP_VALUE_RSP 2
70 #define IDX_GET_CURR_APP_VAL_RSP 3
71 #define IDX_SET_APP_VAL_RSP 4
72 #define IDX_GET_APP_ATTR_TXT_RSP 5
73 #define IDX_GET_APP_VAL_TXT_RSP 6
74 #define IDX_GET_ELEMENT_ATTR_RSP 7
75 #define MAX_VOLUME 128
77 #define MAX_TRANSACTIONS_PER_SESSION 16
78 #define MAX_CMD_QUEUE_LEN 8
79 #define PLAY_STATUS_PLAYING 1
81 #define CHECK_RC_CONNECTED \
82 BTIF_TRACE_DEBUG("## %s ##", __FUNCTION__); \
83 if (btif_rc_cb.rc_connected == FALSE) \
85 BTIF_TRACE_WARNING("Function %s() called when RC is not connected", __FUNCTION__); \
86 return BT_STATUS_NOT_READY; \
89 #define FILL_PDU_QUEUE(index, ctype, label, pending) \
91 btif_rc_cb.rc_pdu_info[index].ctype = ctype; \
92 btif_rc_cb.rc_pdu_info[index].label = label; \
93 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = pending; \
96 #define SEND_METAMSG_RSP(index, avrc_rsp) \
98 if (btif_rc_cb.rc_pdu_info[index].is_rsp_pending == FALSE) \
100 BTIF_TRACE_WARNING("%s Not sending response as no PDU was registered", __FUNCTION__); \
101 return BT_STATUS_UNHANDLED; \
103 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_pdu_info[index].label, \
104 btif_rc_cb.rc_pdu_info[index].ctype, avrc_rsp); \
105 btif_rc_cb.rc_pdu_info[index].ctype = 0; \
106 btif_rc_cb.rc_pdu_info[index].label = 0; \
107 btif_rc_cb.rc_pdu_info[index].is_rsp_pending = FALSE; \
110 /*****************************************************************************
111 ** Local type definitions
112 ******************************************************************************/
116 } btif_rc_reg_notifications_t;
122 BOOLEAN is_rsp_pending;
123 } btif_rc_cmd_ctxt_t;
125 /* 2 second timeout to get interim response */
126 #define BTIF_TIMEOUT_RC_INTERIM_RSP_MS (2 * 1000)
127 #define BTIF_TIMEOUT_RC_STATUS_CMD_MS (2 * 1000)
128 #define BTIF_TIMEOUT_RC_CONTROL_CMD_MS (2 * 1000)
136 } btif_rc_nfn_reg_status_t;
141 btif_rc_nfn_reg_status_t status;
142 } btif_rc_supported_event_t;
144 #define BTIF_RC_STS_TIMEOUT 0xFE
148 } btif_rc_status_cmd_timer_t;
153 } btif_rc_control_cmd_timer_t;
157 btif_rc_status_cmd_timer_t rc_status_cmd;
158 btif_rc_control_cmd_timer_t rc_control_cmd;
160 } btif_rc_timer_context_t;
163 BOOLEAN query_started;
168 UINT8 ext_attr_index;
170 btrc_player_app_attr_t attrs[AVRC_MAX_APP_ATTR_SIZE];
171 btrc_player_app_ext_attr_t ext_attrs[AVRC_MAX_APP_ATTR_SIZE];
172 } btif_rc_player_app_settings_t;
174 /* TODO : Merge btif_rc_reg_notifications_t and btif_rc_cmd_ctxt_t to a single struct */
176 BOOLEAN rc_connected;
178 tBTA_AV_FEAT rc_features;
180 UINT16 rc_pending_play;
181 btif_rc_cmd_ctxt_t rc_pdu_info[MAX_CMD_QUEUE_LEN];
182 btif_rc_reg_notifications_t rc_notif[MAX_RC_NOTIFICATIONS];
183 unsigned int rc_volume;
184 uint8_t rc_vol_label;
185 list_t *rc_supported_event_list;
186 btif_rc_player_app_settings_t rc_app_settings;
187 alarm_t *rc_play_status_timer;
188 BOOLEAN rc_features_processed;
189 UINT64 rc_playing_uid;
190 BOOLEAN rc_procedure_complete;
197 btif_rc_timer_context_t txn_timer_context;
203 pthread_mutex_t lbllock;
204 rc_transaction_t transaction[MAX_TRANSACTIONS_PER_SESSION];
209 #define MAX_UINPUT_PATHS 3
210 static const char* uinput_dev_path[] =
211 {"/dev/uinput", "/dev/input/uinput", "/dev/misc/uinput" };
212 static int uinput_fd = -1;
214 static int send_event (int fd, uint16_t type, uint16_t code, int32_t value);
215 static void send_key (int fd, uint16_t key, int pressed);
216 static int uinput_driver_check();
217 static int uinput_create(char *name);
218 static int init_uinput (void);
219 static void close_uinput (void);
220 static void sleep_ms(period_ms_t timeout_ms);
222 static const struct {
226 uint8_t release_quirk;
228 { "PLAY", AVRC_ID_PLAY, KEY_PLAYCD, 1 },
229 { "STOP", AVRC_ID_STOP, KEY_STOPCD, 0 },
230 { "PAUSE", AVRC_ID_PAUSE, KEY_PAUSECD, 1 },
231 { "FORWARD", AVRC_ID_FORWARD, KEY_NEXTSONG, 0 },
232 { "BACKWARD", AVRC_ID_BACKWARD, KEY_PREVIOUSSONG, 0 },
233 { "REWIND", AVRC_ID_REWIND, KEY_REWIND, 0 },
234 { "FAST FORWARD", AVRC_ID_FAST_FOR, KEY_FAST_FORWARD, 0 },
238 static void send_reject_response (UINT8 rc_handle, UINT8 label,
239 UINT8 pdu, UINT8 status);
240 static UINT8 opcode_from_pdu(UINT8 pdu);
241 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label,
242 tBTA_AV_CODE code, tAVRC_RESPONSE *pmetamsg_resp);
243 static void register_volumechange(UINT8 label);
244 static void lbl_init();
245 static void lbl_destroy();
246 static void init_all_transactions();
247 static bt_status_t get_transaction(rc_transaction_t **ptransaction);
248 static void release_transaction(UINT8 label);
249 static rc_transaction_t* get_transaction_by_lbl(UINT8 label);
250 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
251 #if (AVRC_CTLR_INCLUDED == TRUE)
252 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg);
253 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg);
254 static void btif_rc_ctrl_upstreams_rsp_cmd(
255 UINT8 event, tAVRC_COMMAND *pavrc_cmd, UINT8 label);
256 static void btif_rc_ctrl_upstreams_rsp_evt(
257 UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8* p_buf, UINT16 buf_len, UINT8 rsp_type);
258 static void rc_ctrl_procedure_complete();
259 static void rc_stop_play_status_timer();
260 static void register_for_event_notification (btif_rc_supported_event_t *p_event);
261 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp);
262 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp);
263 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp);
264 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp);
265 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
266 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp);
267 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp);
268 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_ELEM_ATTRS_RSP *p_rsp);
269 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp);
270 static bt_status_t get_play_status_cmd(void);
271 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs);
272 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals);
273 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value);
274 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids);
275 static bt_status_t getcapabilities_cmd (uint8_t cap_id);
276 static bt_status_t list_player_app_setting_attrib_cmd(void);
277 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id);
278 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids);
280 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND* p_param, UINT8 ctype, UINT8 label);
281 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label);
282 static void rc_start_play_status_timer(void);
283 static bool absolute_volume_disabled(void);
285 /*****************************************************************************
287 ******************************************************************************/
288 static btif_rc_cb_t btif_rc_cb;
289 static btrc_callbacks_t *bt_rc_callbacks = NULL;
290 static btrc_ctrl_callbacks_t *bt_rc_ctrl_callbacks = NULL;
292 /*****************************************************************************
294 ******************************************************************************/
296 /*****************************************************************************
298 ******************************************************************************/
299 extern BOOLEAN btif_hf_call_terminated_recently();
300 extern BOOLEAN check_cod(const bt_bdaddr_t *remote_bdaddr, uint32_t cod);
302 extern fixed_queue_t *btu_general_alarm_queue;
304 /*****************************************************************************
306 ******************************************************************************/
308 /*****************************************************************************
309 ** Local uinput helper functions
310 ******************************************************************************/
311 int send_event (int fd, uint16_t type, uint16_t code, int32_t value)
313 struct uinput_event event;
314 BTIF_TRACE_DEBUG("%s type:%u code:%u value:%d", __FUNCTION__,
316 memset(&event, 0, sizeof(event));
321 return write(fd, &event, sizeof(event));
324 void send_key (int fd, uint16_t key, int pressed)
326 BTIF_TRACE_DEBUG("%s fd:%d key:%u pressed:%d", __FUNCTION__,
334 BTIF_TRACE_DEBUG("AVRCP: Send key %d (%d) fd=%d", key, pressed, fd);
335 send_event(fd, EV_KEY, key, pressed);
336 send_event(fd, EV_SYN, SYN_REPORT, 0);
339 /************** uinput related functions **************/
340 int uinput_driver_check()
343 for (i=0; i < MAX_UINPUT_PATHS; i++)
345 if (access(uinput_dev_path[i], O_RDWR) == 0) {
349 BTIF_TRACE_ERROR("%s ERROR: uinput device is not in the system", __FUNCTION__);
353 int uinput_create(char *name)
355 struct uinput_dev dev;
358 for(x=0; x < MAX_UINPUT_PATHS; x++)
360 fd = open(uinput_dev_path[x], O_RDWR);
365 if (x == MAX_UINPUT_PATHS) {
366 BTIF_TRACE_ERROR("%s ERROR: uinput device open failed", __FUNCTION__);
369 memset(&dev, 0, sizeof(dev));
371 strncpy(dev.name, name, UINPUT_MAX_NAME_SIZE-1);
373 dev.id.bustype = BUS_BLUETOOTH;
374 dev.id.vendor = 0x0000;
375 dev.id.product = 0x0000;
376 dev.id.version = 0x0000;
378 if (write(fd, &dev, sizeof(dev)) < 0) {
379 BTIF_TRACE_ERROR("%s Unable to write device information", __FUNCTION__);
384 ioctl(fd, UI_SET_EVBIT, EV_KEY);
385 ioctl(fd, UI_SET_EVBIT, EV_REL);
386 ioctl(fd, UI_SET_EVBIT, EV_SYN);
388 for (x = 0; key_map[x].name != NULL; x++)
389 ioctl(fd, UI_SET_KEYBIT, key_map[x].mapped_id);
391 if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
392 BTIF_TRACE_ERROR("%s Unable to create uinput device", __FUNCTION__);
399 int init_uinput (void)
401 char *name = "AVRCP";
403 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
404 uinput_fd = uinput_create(name);
406 BTIF_TRACE_ERROR("%s AVRCP: Failed to initialize uinput for %s (%d)",
407 __FUNCTION__, name, uinput_fd);
409 BTIF_TRACE_DEBUG("%s AVRCP: Initialized uinput for %s (fd=%d)",
410 __FUNCTION__, name, uinput_fd);
415 void close_uinput (void)
417 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
419 ioctl(uinput_fd, UI_DEV_DESTROY);
426 #if (AVRC_CTLR_INCLUDED == TRUE)
427 void rc_cleanup_sent_cmd (void *p_data)
429 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
433 void handle_rc_ctrl_features(BD_ADDR bd_addr)
435 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
436 ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
437 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
441 bdcpy(rc_addr.address,bd_addr);
443 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)&&
444 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT))
446 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
448 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)&&
449 (btif_rc_cb.rc_features & BTA_AV_FEAT_VENDOR)&&
450 (btif_rc_cb.rc_features_processed != TRUE))
452 rc_features |= BTRC_FEAT_METADATA;
453 /* Mark rc features processed to avoid repeating
454 * the AVRCP procedure every time on receiving this
457 btif_rc_cb.rc_features_processed = TRUE;
458 getcapabilities_cmd (AVRC_CAP_COMPANY_ID);
460 BTIF_TRACE_DEBUG("%s Update rc features to CTRL %d", __FUNCTION__, rc_features);
461 HAL_CBACK(bt_rc_ctrl_callbacks, getrcfeatures_cb, &rc_addr, rc_features);
466 void handle_rc_features(BD_ADDR bd_addr)
468 if (bt_rc_callbacks != NULL)
470 btrc_remote_features_t rc_features = BTRC_FEAT_NONE;
472 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
474 if (interop_match(INTEROP_DISABLE_ABSOLUTE_VOLUME, &rc_addr)
475 || absolute_volume_disabled())
476 btif_rc_cb.rc_features &= ~BTA_AV_FEAT_ADV_CTRL;
478 if (btif_rc_cb.rc_features & BTA_AV_FEAT_BROWSE)
480 rc_features |= BTRC_FEAT_BROWSE;
483 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
484 if ( (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL) &&
485 (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG))
487 rc_features |= BTRC_FEAT_ABSOLUTE_VOLUME;
491 if (btif_rc_cb.rc_features & BTA_AV_FEAT_METADATA)
493 rc_features |= BTRC_FEAT_METADATA;
496 BTIF_TRACE_DEBUG("%s: rc_features=0x%x", __FUNCTION__, rc_features);
497 HAL_CBACK(bt_rc_callbacks, remote_features_cb, &rc_addr, rc_features)
499 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
500 BTIF_TRACE_DEBUG("%s Checking for feature flags in btif_rc_handler with label %d",
501 __FUNCTION__, btif_rc_cb.rc_vol_label);
502 // Register for volume change on connect
503 if (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL &&
504 btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
506 rc_transaction_t *p_transaction=NULL;
507 bt_status_t status = BT_STATUS_NOT_READY;
508 if (MAX_LABEL==btif_rc_cb.rc_vol_label)
510 status=get_transaction(&p_transaction);
514 p_transaction=get_transaction_by_lbl(btif_rc_cb.rc_vol_label);
515 if (NULL!=p_transaction)
517 BTIF_TRACE_DEBUG("%s register_volumechange already in progress for label %d",
518 __FUNCTION__, btif_rc_cb.rc_vol_label);
522 status=get_transaction(&p_transaction);
525 if (BT_STATUS_SUCCESS == status && NULL!=p_transaction)
527 btif_rc_cb.rc_vol_label=p_transaction->lbl;
528 register_volumechange(btif_rc_cb.rc_vol_label);
535 /***************************************************************************
536 * Function handle_rc_connect
538 * - Argument: tBTA_AV_RC_OPEN RC open data structure
540 * - Description: RC connection event handler
542 ***************************************************************************/
543 void handle_rc_connect (tBTA_AV_RC_OPEN *p_rc_open)
545 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_open->rc_handle);
546 bt_status_t result = BT_STATUS_SUCCESS;
547 #if (AVRC_CTLR_INCLUDED == TRUE)
551 if (p_rc_open->status == BTA_AV_SUCCESS)
553 //check if already some RC is connected
554 if (btif_rc_cb.rc_connected)
556 BTIF_TRACE_ERROR("%s Got RC OPEN in connected state, Connected RC: %d \
557 and Current RC: %d", __FUNCTION__, btif_rc_cb.rc_handle,p_rc_open->rc_handle );
558 if ((btif_rc_cb.rc_handle != p_rc_open->rc_handle)
559 && (bdcmp(btif_rc_cb.rc_addr, p_rc_open->peer_addr)))
561 BTIF_TRACE_DEBUG("%s Got RC connected for some other handle", __FUNCTION__);
562 BTA_AvCloseRc(p_rc_open->rc_handle);
566 memcpy(btif_rc_cb.rc_addr, p_rc_open->peer_addr, sizeof(BD_ADDR));
567 btif_rc_cb.rc_features = p_rc_open->peer_features;
568 btif_rc_cb.rc_vol_label=MAX_LABEL;
569 btif_rc_cb.rc_volume=MAX_VOLUME;
571 btif_rc_cb.rc_connected = TRUE;
572 btif_rc_cb.rc_handle = p_rc_open->rc_handle;
574 /* on locally initiated connection we will get remote features as part of connect */
575 if (btif_rc_cb.rc_features != 0)
576 handle_rc_features(btif_rc_cb.rc_addr);
579 result = uinput_driver_check();
580 if (result == BT_STATUS_SUCCESS)
587 BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not initializing UInput",
590 BTIF_TRACE_DEBUG("%s handle_rc_connect features %d ",__FUNCTION__, btif_rc_cb.rc_features);
591 #if (AVRC_CTLR_INCLUDED == TRUE)
592 btif_rc_cb.rc_playing_uid = RC_INVALID_TRACK_ID;
593 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
594 if (bt_rc_ctrl_callbacks != NULL)
596 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, TRUE, &rc_addr);
598 /* report connection state if remote device is AVRCP target */
599 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)||
600 ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCCT)&&
601 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL)))
603 handle_rc_ctrl_features(btif_rc_cb.rc_addr);
609 BTIF_TRACE_ERROR("%s Connect failed with error code: %d",
610 __FUNCTION__, p_rc_open->status);
611 btif_rc_cb.rc_connected = FALSE;
615 /***************************************************************************
616 * Function handle_rc_disconnect
618 * - Argument: tBTA_AV_RC_CLOSE RC close data structure
620 * - Description: RC disconnection event handler
622 ***************************************************************************/
623 void handle_rc_disconnect (tBTA_AV_RC_CLOSE *p_rc_close)
625 #if (AVRC_CTLR_INCLUDED == TRUE)
627 tBTA_AV_FEAT features;
629 BTIF_TRACE_DEBUG("%s: rc_handle: %d", __FUNCTION__, p_rc_close->rc_handle);
630 if ((p_rc_close->rc_handle != btif_rc_cb.rc_handle)
631 && (bdcmp(btif_rc_cb.rc_addr, p_rc_close->peer_addr)))
633 BTIF_TRACE_ERROR("Got disconnect of unknown device");
636 #if (AVRC_CTLR_INCLUDED == TRUE)
637 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
638 features = btif_rc_cb.rc_features;
639 /* Clean up AVRCP procedure flags */
640 memset(&btif_rc_cb.rc_app_settings, 0,
641 sizeof(btif_rc_player_app_settings_t));
642 btif_rc_cb.rc_features_processed = FALSE;
643 btif_rc_cb.rc_procedure_complete = FALSE;
644 rc_stop_play_status_timer();
645 /* Check and clear the notification event list */
646 if (btif_rc_cb.rc_supported_event_list != NULL)
648 list_clear(btif_rc_cb.rc_supported_event_list);
649 btif_rc_cb.rc_supported_event_list = NULL;
652 btif_rc_cb.rc_handle = 0;
653 btif_rc_cb.rc_connected = FALSE;
654 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
655 memset(btif_rc_cb.rc_notif, 0, sizeof(btif_rc_cb.rc_notif));
657 btif_rc_cb.rc_features = 0;
658 btif_rc_cb.rc_vol_label=MAX_LABEL;
659 btif_rc_cb.rc_volume=MAX_VOLUME;
660 init_all_transactions();
661 if (bt_rc_callbacks != NULL)
667 BTIF_TRACE_WARNING("%s Avrcp TG role not enabled, not closing UInput", __FUNCTION__);
670 memset(btif_rc_cb.rc_addr, 0, sizeof(BD_ADDR));
671 #if (AVRC_CTLR_INCLUDED == TRUE)
672 /* report connection state if device is AVRCP target */
673 if (bt_rc_ctrl_callbacks != NULL)
675 HAL_CBACK(bt_rc_ctrl_callbacks, connection_state_cb, FALSE, &rc_addr);
680 /***************************************************************************
681 * Function handle_rc_passthrough_cmd
683 * - Argument: tBTA_AV_RC rc_id remote control command ID
684 * tBTA_AV_STATE key_state status of key press
686 * - Description: Remote control command handler
688 ***************************************************************************/
689 void handle_rc_passthrough_cmd ( tBTA_AV_REMOTE_CMD *p_remote_cmd)
694 BTIF_TRACE_DEBUG("%s: p_remote_cmd->rc_id=%d", __FUNCTION__, p_remote_cmd->rc_id);
696 /* If AVRC is open and peer sends PLAY but there is no AVDT, then we queue-up this PLAY */
699 /* queue AVRC PLAY if GAVDTP Open notification to app is pending (2 second timer) */
700 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY) && (!btif_av_is_connected()))
702 if (p_remote_cmd->key_state == AVRC_STATE_PRESS)
704 APPL_TRACE_WARNING("%s: AVDT not open, queuing the PLAY command", __FUNCTION__);
705 btif_rc_cb.rc_pending_play = TRUE;
710 if ((p_remote_cmd->rc_id == BTA_AV_RC_PAUSE) && (btif_rc_cb.rc_pending_play))
712 APPL_TRACE_WARNING("%s: Clear the pending PLAY on PAUSE received", __FUNCTION__);
713 btif_rc_cb.rc_pending_play = FALSE;
716 if ((p_remote_cmd->rc_id == BTA_AV_RC_VOL_UP)||(p_remote_cmd->rc_id == BTA_AV_RC_VOL_DOWN))
717 return; // this command is not to be sent to UINPUT, only needed for PTS
720 if ((p_remote_cmd->rc_id == BTA_AV_RC_STOP) && (!btif_av_stream_started_ready()))
722 APPL_TRACE_WARNING("%s: Stream suspended, ignore STOP cmd",__FUNCTION__);
726 if (p_remote_cmd->key_state == AVRC_STATE_RELEASE) {
734 /* If this is Play/Pause command (press or release) before processing, check the following
735 * a voice call has ended recently
736 * the remote device is not of type headset
737 * If the above conditions meet, drop the Play/Pause command
738 * This fix is to interop with certain carkits which sends an automatic PLAY or PAUSE
739 * commands right after call ends
741 if ((p_remote_cmd->rc_id == BTA_AV_RC_PLAY || p_remote_cmd->rc_id == BTA_AV_RC_PAUSE)&&
742 (btif_hf_call_terminated_recently() == TRUE) &&
743 (check_cod( (const bt_bdaddr_t*)&(btif_rc_cb.rc_addr), COD_AV_HEADSETS) != TRUE))
745 BTIF_TRACE_DEBUG("%s:Dropping the play/Pause command received right after call end cmd:%d",
746 __FUNCTION__,p_remote_cmd->rc_id);
750 if (p_remote_cmd->rc_id == BTA_AV_RC_FAST_FOR || p_remote_cmd->rc_id == BTA_AV_RC_REWIND) {
751 HAL_CBACK(bt_rc_callbacks, passthrough_cmd_cb, p_remote_cmd->rc_id, pressed);
755 for (i = 0; key_map[i].name != NULL; i++) {
756 if (p_remote_cmd->rc_id == key_map[i].avrcp) {
757 BTIF_TRACE_DEBUG("%s: %s %s", __FUNCTION__, key_map[i].name, status);
759 /* MusicPlayer uses a long_press_timeout of 1 second for PLAYPAUSE button
760 * and maps that to autoshuffle. So if for some reason release for PLAY/PAUSE
761 * comes 1 second after the press, the MediaPlayer UI goes into a bad state.
762 * The reason for the delay could be sniff mode exit or some AVDTP procedure etc.
763 * The fix is to generate a release right after the press and drown the 'actual'
766 if ((key_map[i].release_quirk == 1) && (pressed == 0))
768 BTIF_TRACE_DEBUG("%s: AVRC %s Release Faked earlier, drowned now",
769 __FUNCTION__, key_map[i].name);
772 send_key(uinput_fd, key_map[i].mapped_id, pressed);
773 if ((key_map[i].release_quirk == 1) && (pressed == 1))
776 BTIF_TRACE_DEBUG("%s: AVRC %s Release quirk enabled, send release now",
777 __FUNCTION__, key_map[i].name);
778 send_key(uinput_fd, key_map[i].mapped_id, 0);
784 if (key_map[i].name == NULL)
785 BTIF_TRACE_ERROR("%s AVRCP: unknown button 0x%02X %s", __FUNCTION__,
786 p_remote_cmd->rc_id, status);
789 /***************************************************************************
790 * Function handle_rc_passthrough_rsp
792 * - Argument: tBTA_AV_REMOTE_RSP passthrough command response
794 * - Description: Remote control passthrough response handler
796 ***************************************************************************/
797 void handle_rc_passthrough_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
799 #if (AVRC_CTLR_INCLUDED == TRUE)
801 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
804 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
815 BTIF_TRACE_DEBUG("%s: rc_id=%d status=%s", __FUNCTION__, p_remote_rsp->rc_id, status);
817 release_transaction(p_remote_rsp->label);
818 if (bt_rc_ctrl_callbacks != NULL) {
819 HAL_CBACK(bt_rc_ctrl_callbacks, passthrough_rsp_cb, p_remote_rsp->rc_id, key_state);
824 BTIF_TRACE_ERROR("%s DUT does not support AVRCP controller role", __FUNCTION__);
827 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
831 /***************************************************************************
832 * Function handle_rc_vendorunique_rsp
834 * - Argument: tBTA_AV_REMOTE_RSP command response
836 * - Description: Remote control vendor unique response handler
838 ***************************************************************************/
839 void handle_rc_vendorunique_rsp ( tBTA_AV_REMOTE_RSP *p_remote_rsp)
841 #if (AVRC_CTLR_INCLUDED == TRUE)
844 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
847 if (p_remote_rsp->key_state == AVRC_STATE_RELEASE)
858 if (p_remote_rsp->len > 0)
860 if (p_remote_rsp->len >= AVRC_PASS_THRU_GROUP_LEN)
861 vendor_id = p_remote_rsp->p_data[AVRC_PASS_THRU_GROUP_LEN -1];
862 osi_free_and_reset((void **)&p_remote_rsp->p_data);
864 BTIF_TRACE_DEBUG("%s: vendor_id=%d status=%s", __FUNCTION__, vendor_id, status);
866 release_transaction(p_remote_rsp->label);
867 HAL_CBACK(bt_rc_ctrl_callbacks, groupnavigation_rsp_cb, vendor_id, key_state);
871 BTIF_TRACE_ERROR("%s Remote does not support AVRCP TG role", __FUNCTION__);
874 BTIF_TRACE_ERROR("%s AVRCP controller role is not enabled", __FUNCTION__);
878 void handle_uid_changed_notification(tBTA_AV_META_MSG *pmeta_msg, tAVRC_COMMAND *pavrc_command)
880 tAVRC_RESPONSE avrc_rsp = {0};
881 avrc_rsp.rsp.pdu = pavrc_command->pdu;
882 avrc_rsp.rsp.status = AVRC_STS_NO_ERROR;
883 avrc_rsp.rsp.opcode = pavrc_command->cmd.opcode;
885 avrc_rsp.reg_notif.event_id = pavrc_command->reg_notif.event_id;
886 avrc_rsp.reg_notif.param.uid_counter = 0;
888 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_INTERIM, &avrc_rsp);
889 send_metamsg_rsp(pmeta_msg->rc_handle, pmeta_msg->label, AVRC_RSP_CHANGED, &avrc_rsp);
893 /***************************************************************************
894 * Function handle_rc_metamsg_cmd
896 * - Argument: tBTA_AV_VENDOR Structure containing the received
899 * - Description: Remote control metamsg command handler (AVRCP 1.3)
901 ***************************************************************************/
902 void handle_rc_metamsg_cmd (tBTA_AV_META_MSG *pmeta_msg)
904 /* Parse the metamsg command and pass it on to BTL-IFS */
905 UINT8 scratch_buf[512] = {0};
906 tAVRC_COMMAND avrc_command = {0};
909 BTIF_TRACE_EVENT("+ %s", __FUNCTION__);
911 if (pmeta_msg->p_msg->hdr.opcode != AVRC_OP_VENDOR)
913 BTIF_TRACE_WARNING("Invalid opcode: %x", pmeta_msg->p_msg->hdr.opcode);
916 if (pmeta_msg->len < 3)
918 BTIF_TRACE_WARNING("Invalid length.Opcode: 0x%x, len: 0x%x", pmeta_msg->p_msg->hdr.opcode,
923 if (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)
925 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
927 rc_transaction_t *transaction=NULL;
928 transaction=get_transaction_by_lbl(pmeta_msg->label);
929 if (NULL!=transaction)
931 handle_rc_metamsg_rsp(pmeta_msg);
935 BTIF_TRACE_DEBUG("%s:Discard vendor dependent rsp. code: %d label:%d.",
936 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
942 BTIF_TRACE_DEBUG("%s:Received vendor dependent rsp. code: %d len: %d. Not processing it.",
943 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
949 status=AVRC_ParsCommand(pmeta_msg->p_msg, &avrc_command, scratch_buf, sizeof(scratch_buf));
950 BTIF_TRACE_DEBUG("%s Received vendor command.code,PDU and label: %d, %d,%d",
951 __FUNCTION__, pmeta_msg->code, avrc_command.cmd.pdu, pmeta_msg->label);
953 if (status != AVRC_STS_NO_ERROR)
956 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
957 __FUNCTION__, status);
958 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_command.pdu, status);
962 /* if RegisterNotification, add it to our registered queue */
964 if (avrc_command.cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
966 UINT8 event_id = avrc_command.reg_notif.event_id;
967 BTIF_TRACE_EVENT("%s:New register notification received.event_id:%s,label:0x%x,code:%x",
968 __FUNCTION__,dump_rc_notification_event_id(event_id), pmeta_msg->label,pmeta_msg->code);
969 btif_rc_cb.rc_notif[event_id-1].bNotify = TRUE;
970 btif_rc_cb.rc_notif[event_id-1].label = pmeta_msg->label;
972 if (event_id == AVRC_EVT_UIDS_CHANGE)
974 handle_uid_changed_notification(pmeta_msg, &avrc_command);
980 BTIF_TRACE_EVENT("%s: Passing received metamsg command to app. pdu: %s",
981 __FUNCTION__, dump_rc_pdu(avrc_command.cmd.pdu));
983 /* Since handle_rc_metamsg_cmd() itself is called from
984 *btif context, no context switching is required. Invoke
985 * btif_rc_upstreams_evt directly from here. */
986 btif_rc_upstreams_evt((uint16_t)avrc_command.cmd.pdu, &avrc_command, pmeta_msg->code,
991 /***************************************************************************
993 ** Function btif_rc_handler
995 ** Description RC event handler
997 ***************************************************************************/
998 void btif_rc_handler(tBTA_AV_EVT event, tBTA_AV *p_data)
1000 BTIF_TRACE_DEBUG ("%s event:%s", __FUNCTION__, dump_rc_event(event));
1003 case BTA_AV_RC_OPEN_EVT:
1005 BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_open.peer_features);
1006 handle_rc_connect( &(p_data->rc_open) );
1009 case BTA_AV_RC_CLOSE_EVT:
1011 handle_rc_disconnect( &(p_data->rc_close) );
1014 case BTA_AV_REMOTE_CMD_EVT:
1016 if (bt_rc_callbacks != NULL)
1018 BTIF_TRACE_DEBUG("%s rc_id:0x%x key_state:%d",
1019 __FUNCTION__, p_data->remote_cmd.rc_id,
1020 p_data->remote_cmd.key_state);
1021 /** In race conditions just after 2nd AVRCP is connected
1022 * remote might send pass through commands, so check for
1023 * Rc handle before processing pass through commands
1025 if (btif_rc_cb.rc_handle == p_data->remote_cmd.rc_handle)
1027 handle_rc_passthrough_cmd( (&p_data->remote_cmd) );
1031 BTIF_TRACE_DEBUG("%s Pass-through command for Invalid rc handle", __FUNCTION__);
1036 BTIF_TRACE_ERROR("AVRCP TG role not up, drop passthrough commands");
1041 #if (AVRC_CTLR_INCLUDED == TRUE)
1042 case BTA_AV_REMOTE_RSP_EVT:
1044 BTIF_TRACE_DEBUG("%s RSP: rc_id:0x%x key_state:%d",
1045 __FUNCTION__, p_data->remote_rsp.rc_id, p_data->remote_rsp.key_state);
1046 if (p_data->remote_rsp.rc_id == AVRC_ID_VENDOR)
1048 handle_rc_vendorunique_rsp(&p_data->remote_rsp);
1052 handle_rc_passthrough_rsp(&p_data->remote_rsp);
1058 case BTA_AV_RC_FEAT_EVT:
1060 BTIF_TRACE_DEBUG("%s Peer_features:%x", __FUNCTION__, p_data->rc_feat.peer_features);
1061 btif_rc_cb.rc_features = p_data->rc_feat.peer_features;
1062 handle_rc_features(p_data->rc_feat.peer_addr);
1063 #if (AVRC_CTLR_INCLUDED == TRUE)
1064 if ((btif_rc_cb.rc_connected) && (bt_rc_ctrl_callbacks != NULL))
1066 handle_rc_ctrl_features(btif_rc_cb.rc_addr);
1072 case BTA_AV_META_MSG_EVT:
1074 if (bt_rc_callbacks != NULL)
1076 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT code:%d label:%d",
1078 p_data->meta_msg.code,
1079 p_data->meta_msg.label);
1080 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1082 p_data->meta_msg.company_id,
1083 p_data->meta_msg.len,
1084 p_data->meta_msg.rc_handle);
1085 /* handle the metamsg command */
1086 handle_rc_metamsg_cmd(&(p_data->meta_msg));
1087 /* Free the Memory allocated for tAVRC_MSG */
1089 #if (AVRC_CTLR_INCLUDED == TRUE)
1090 else if ((bt_rc_callbacks == NULL)&&(bt_rc_ctrl_callbacks != NULL))
1092 /* This is case of Sink + CT + TG(for abs vol)) */
1093 BTIF_TRACE_DEBUG("%s BTA_AV_META_MSG_EVT code:%d label:%d",
1095 p_data->meta_msg.code,
1096 p_data->meta_msg.label);
1097 BTIF_TRACE_DEBUG("%s company_id:0x%x len:%d handle:%d",
1099 p_data->meta_msg.company_id,
1100 p_data->meta_msg.len,
1101 p_data->meta_msg.rc_handle);
1102 if ((p_data->meta_msg.code >= AVRC_RSP_NOT_IMPL)&&
1103 (p_data->meta_msg.code <= AVRC_RSP_INTERIM))
1105 /* Its a response */
1106 handle_avk_rc_metamsg_rsp(&(p_data->meta_msg));
1108 else if (p_data->meta_msg.code <= AVRC_CMD_GEN_INQ)
1111 handle_avk_rc_metamsg_cmd(&(p_data->meta_msg));
1118 BTIF_TRACE_ERROR("Neither CTRL, nor TG is up, drop meta commands");
1124 BTIF_TRACE_DEBUG("%s Unhandled RC event : 0x%x", __FUNCTION__, event);
1128 /***************************************************************************
1130 ** Function btif_rc_get_connected_peer
1132 ** Description Fetches the connected headset's BD_ADDR if any
1134 ***************************************************************************/
1135 BOOLEAN btif_rc_get_connected_peer(BD_ADDR peer_addr)
1137 if (btif_rc_cb.rc_connected == TRUE) {
1138 bdcpy(peer_addr, btif_rc_cb.rc_addr);
1144 /***************************************************************************
1146 ** Function btif_rc_get_connected_peer_handle
1148 ** Description Fetches the connected headset's handle if any
1150 ***************************************************************************/
1151 UINT8 btif_rc_get_connected_peer_handle(void)
1153 return btif_rc_cb.rc_handle;
1156 /***************************************************************************
1158 ** Function btif_rc_check_handle_pending_play
1160 ** Description Clears the queued PLAY command. if bSend is TRUE, forwards to app
1162 ***************************************************************************/
1164 /* clear the queued PLAY command. if bSend is TRUE, forward to app */
1165 void btif_rc_check_handle_pending_play (BD_ADDR peer_addr, BOOLEAN bSendToApp)
1169 BTIF_TRACE_DEBUG("%s: bSendToApp=%d", __FUNCTION__, bSendToApp);
1170 if (btif_rc_cb.rc_pending_play)
1174 tBTA_AV_REMOTE_CMD remote_cmd;
1175 APPL_TRACE_DEBUG("%s: Sending queued PLAYED event to app", __FUNCTION__);
1177 memset (&remote_cmd, 0, sizeof(tBTA_AV_REMOTE_CMD));
1178 remote_cmd.rc_handle = btif_rc_cb.rc_handle;
1179 remote_cmd.rc_id = AVRC_ID_PLAY;
1180 remote_cmd.hdr.ctype = AVRC_CMD_CTRL;
1181 remote_cmd.hdr.opcode = AVRC_OP_PASS_THRU;
1183 /* delay sending to app, else there is a timing issue in the framework,
1184 ** which causes the audio to be on th device's speaker. Delay between
1188 /* send to app - both PRESSED & RELEASED */
1189 remote_cmd.key_state = AVRC_STATE_PRESS;
1190 handle_rc_passthrough_cmd( &remote_cmd );
1194 remote_cmd.key_state = AVRC_STATE_RELEASE;
1195 handle_rc_passthrough_cmd( &remote_cmd );
1197 btif_rc_cb.rc_pending_play = FALSE;
1201 /* Generic reject response */
1202 static void send_reject_response (UINT8 rc_handle, UINT8 label, UINT8 pdu, UINT8 status)
1204 UINT8 ctype = AVRC_RSP_REJ;
1205 tAVRC_RESPONSE avrc_rsp;
1206 BT_HDR *p_msg = NULL;
1207 memset (&avrc_rsp, 0, sizeof(tAVRC_RESPONSE));
1209 avrc_rsp.rsp.opcode = opcode_from_pdu(pdu);
1210 avrc_rsp.rsp.pdu = pdu;
1211 avrc_rsp.rsp.status = status;
1213 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(rc_handle, &avrc_rsp, &p_msg)) )
1215 BTIF_TRACE_DEBUG("%s:Sending error notification to handle:%d. pdu:%s,status:0x%02x",
1216 __FUNCTION__, rc_handle, dump_rc_pdu(pdu), status);
1217 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1221 /***************************************************************************
1222 * Function send_metamsg_rsp
1225 * rc_handle RC handle corresponding to the connected RC
1226 * label Label of the RC response
1227 * code Response type
1228 * pmetamsg_resp Vendor response
1230 * - Description: Remote control metamsg response handler (AVRCP 1.3)
1232 ***************************************************************************/
1233 static void send_metamsg_rsp (UINT8 rc_handle, UINT8 label, tBTA_AV_CODE code,
1234 tAVRC_RESPONSE *pmetamsg_resp)
1240 BTIF_TRACE_WARNING("%s: Invalid response received from application", __FUNCTION__);
1244 BTIF_TRACE_EVENT("+%s: rc_handle: %d, label: %d, code: 0x%02x, pdu: %s", __FUNCTION__,
1245 rc_handle, label, code, dump_rc_pdu(pmetamsg_resp->rsp.pdu));
1247 if (pmetamsg_resp->rsp.status != AVRC_STS_NO_ERROR)
1249 ctype = AVRC_RSP_REJ;
1253 if ( code < AVRC_RSP_NOT_IMPL)
1255 if (code == AVRC_CMD_NOTIF)
1257 ctype = AVRC_RSP_INTERIM;
1259 else if (code == AVRC_CMD_STATUS)
1261 ctype = AVRC_RSP_IMPL_STBL;
1265 ctype = AVRC_RSP_ACCEPT;
1273 /* if response is for register_notification, make sure the rc has
1274 actually registered for this */
1275 if ((pmetamsg_resp->rsp.pdu == AVRC_PDU_REGISTER_NOTIFICATION) && (code == AVRC_RSP_CHANGED))
1277 BOOLEAN bSent = FALSE;
1278 UINT8 event_id = pmetamsg_resp->reg_notif.event_id;
1279 BOOLEAN bNotify = (btif_rc_cb.rc_connected) && (btif_rc_cb.rc_notif[event_id-1].bNotify);
1281 /* de-register this notification for a CHANGED response */
1282 btif_rc_cb.rc_notif[event_id-1].bNotify = FALSE;
1283 BTIF_TRACE_DEBUG("%s rc_handle: %d. event_id: 0x%02d bNotify:%u", __FUNCTION__,
1284 btif_rc_cb.rc_handle, event_id, bNotify);
1287 BT_HDR *p_msg = NULL;
1290 if (AVRC_STS_NO_ERROR == (status = AVRC_BldResponse(btif_rc_cb.rc_handle,
1291 pmetamsg_resp, &p_msg)) )
1293 BTIF_TRACE_DEBUG("%s Sending notification to rc_handle: %d. event_id: 0x%02d",
1294 __FUNCTION__, btif_rc_cb.rc_handle, event_id);
1296 BTA_AvMetaRsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1301 BTIF_TRACE_WARNING("%s failed to build metamsg response. status: 0x%02x",
1302 __FUNCTION__, status);
1309 BTIF_TRACE_DEBUG("%s: Notification not sent, as there are no RC connections or the \
1310 CT has not subscribed for event_id: %s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1315 /* All other commands go here */
1317 BT_HDR *p_msg = NULL;
1320 status = AVRC_BldResponse(rc_handle, pmetamsg_resp, &p_msg);
1322 if (status == AVRC_STS_NO_ERROR)
1324 BTA_AvMetaRsp(rc_handle, label, ctype, p_msg);
1328 BTIF_TRACE_ERROR("%s: failed to build metamsg response. status: 0x%02x",
1329 __FUNCTION__, status);
1334 static UINT8 opcode_from_pdu(UINT8 pdu)
1340 case AVRC_PDU_NEXT_GROUP:
1341 case AVRC_PDU_PREV_GROUP: /* pass thru */
1342 opcode = AVRC_OP_PASS_THRU;
1345 default: /* vendor */
1346 opcode = AVRC_OP_VENDOR;
1353 /*******************************************************************************
1355 ** Function btif_rc_upstreams_evt
1357 ** Description Executes AVRC UPSTREAMS events in btif context.
1361 *******************************************************************************/
1362 static void btif_rc_upstreams_evt(UINT16 event, tAVRC_COMMAND *pavrc_cmd, UINT8 ctype, UINT8 label)
1364 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1365 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle, ctype, label);
1369 case AVRC_PDU_GET_PLAY_STATUS:
1371 FILL_PDU_QUEUE(IDX_GET_PLAY_STATUS_RSP, ctype, label, TRUE)
1372 HAL_CBACK(bt_rc_callbacks, get_play_status_cb);
1375 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
1376 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
1377 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
1378 case AVRC_PDU_SET_PLAYER_APP_VALUE:
1379 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
1380 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
1382 /* TODO: Add support for Application Settings */
1383 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_CMD);
1386 case AVRC_PDU_GET_ELEMENT_ATTR:
1388 btrc_media_attr_t element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1390 memset(&element_attrs, 0, sizeof(element_attrs));
1391 if (pavrc_cmd->get_elem_attrs.num_attr == 0)
1393 /* CT requests for all attributes */
1395 num_attr = BTRC_MAX_ELEM_ATTR_SIZE;
1396 for (attr_cnt = 0; attr_cnt < BTRC_MAX_ELEM_ATTR_SIZE; attr_cnt++)
1398 element_attrs[attr_cnt] = attr_cnt + 1;
1401 else if (pavrc_cmd->get_elem_attrs.num_attr == 0xFF)
1403 /* 0xff indicates, no attributes requested - reject */
1404 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1405 AVRC_STS_BAD_PARAM);
1410 int attr_cnt, filled_attr_count;
1413 /* Attribute IDs from 1 to AVRC_MAX_NUM_MEDIA_ATTR_ID are only valid,
1414 * hence HAL definition limits the attributes to AVRC_MAX_NUM_MEDIA_ATTR_ID.
1415 * Fill only valid entries.
1417 for (attr_cnt = 0; (attr_cnt < pavrc_cmd->get_elem_attrs.num_attr) &&
1418 (num_attr < AVRC_MAX_NUM_MEDIA_ATTR_ID); attr_cnt++)
1420 if ((pavrc_cmd->get_elem_attrs.attrs[attr_cnt] > 0) &&
1421 (pavrc_cmd->get_elem_attrs.attrs[attr_cnt] <= AVRC_MAX_NUM_MEDIA_ATTR_ID))
1423 /* Skip the duplicate entries : PTS sends duplicate entries for Fragment cases
1425 for (filled_attr_count = 0; filled_attr_count < num_attr; filled_attr_count++)
1427 if (element_attrs[filled_attr_count] == pavrc_cmd->get_elem_attrs.attrs[attr_cnt])
1430 if (filled_attr_count == num_attr)
1432 element_attrs[num_attr] = pavrc_cmd->get_elem_attrs.attrs[attr_cnt];
1438 FILL_PDU_QUEUE(IDX_GET_ELEMENT_ATTR_RSP, ctype, label, TRUE);
1439 HAL_CBACK(bt_rc_callbacks, get_element_attr_cb, num_attr, element_attrs);
1442 case AVRC_PDU_REGISTER_NOTIFICATION:
1444 if (pavrc_cmd->reg_notif.event_id == BTRC_EVT_PLAY_POS_CHANGED &&
1445 pavrc_cmd->reg_notif.param == 0)
1447 BTIF_TRACE_WARNING("%s Device registering position changed with illegal param 0.",
1449 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu, AVRC_STS_BAD_PARAM);
1450 /* de-register this notification for a rejected response */
1451 btif_rc_cb.rc_notif[BTRC_EVT_PLAY_POS_CHANGED - 1].bNotify = FALSE;
1454 HAL_CBACK(bt_rc_callbacks, register_notification_cb, pavrc_cmd->reg_notif.event_id,
1455 pavrc_cmd->reg_notif.param);
1458 case AVRC_PDU_INFORM_DISPLAY_CHARSET:
1460 tAVRC_RESPONSE avrc_rsp;
1461 BTIF_TRACE_EVENT("%s() AVRC_PDU_INFORM_DISPLAY_CHARSET", __FUNCTION__);
1462 if (btif_rc_cb.rc_connected == TRUE)
1464 memset(&(avrc_rsp.inform_charset), 0, sizeof(tAVRC_RSP));
1465 avrc_rsp.inform_charset.opcode=opcode_from_pdu(AVRC_PDU_INFORM_DISPLAY_CHARSET);
1466 avrc_rsp.inform_charset.pdu=AVRC_PDU_INFORM_DISPLAY_CHARSET;
1467 avrc_rsp.inform_charset.status=AVRC_STS_NO_ERROR;
1468 send_metamsg_rsp(btif_rc_cb.rc_handle, label, ctype, &avrc_rsp);
1474 send_reject_response (btif_rc_cb.rc_handle, label, pavrc_cmd->pdu,
1475 (pavrc_cmd->pdu == AVRC_PDU_SEARCH)?AVRC_STS_SEARCH_NOT_SUP:AVRC_STS_BAD_CMD);
1482 #if (AVRC_CTLR_INCLUDED == TRUE)
1483 /*******************************************************************************
1485 ** Function btif_rc_ctrl_upstreams_rsp_cmd
1487 ** Description Executes AVRC UPSTREAMS response events in btif context.
1491 *******************************************************************************/
1492 static void btif_rc_ctrl_upstreams_rsp_cmd(UINT8 event, tAVRC_COMMAND *pavrc_cmd,
1495 BTIF_TRACE_DEBUG("%s pdu: %s handle: 0x%x", __FUNCTION__,
1496 dump_rc_pdu(pavrc_cmd->pdu), btif_rc_cb.rc_handle);
1497 bt_bdaddr_t rc_addr;
1498 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
1499 #if (AVRC_CTLR_INCLUDED == TRUE)
1502 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1503 HAL_CBACK(bt_rc_ctrl_callbacks,setabsvol_cmd_cb, &rc_addr,
1504 pavrc_cmd->volume.volume, label);
1506 case AVRC_PDU_REGISTER_NOTIFICATION:
1507 if (pavrc_cmd->reg_notif.event_id == AVRC_EVT_VOLUME_CHANGE)
1509 HAL_CBACK(bt_rc_ctrl_callbacks, registernotification_absvol_cb,
1518 /*******************************************************************************
1520 ** Function btif_rc_upstreams_rsp_evt
1522 ** Description Executes AVRC UPSTREAMS response events in btif context.
1526 *******************************************************************************/
1527 static void btif_rc_upstreams_rsp_evt(UINT16 event, tAVRC_RESPONSE *pavrc_resp, UINT8 ctype, UINT8 label)
1529 BTIF_TRACE_EVENT("%s pdu: %s handle: 0x%x ctype:%x label:%x", __FUNCTION__,
1530 dump_rc_pdu(pavrc_resp->pdu), btif_rc_cb.rc_handle, ctype, label);
1532 #if (AVRC_ADV_CTRL_INCLUDED == TRUE)
1535 case AVRC_PDU_REGISTER_NOTIFICATION:
1537 if (AVRC_RSP_CHANGED==ctype)
1538 btif_rc_cb.rc_volume=pavrc_resp->reg_notif.param.volume;
1539 HAL_CBACK(bt_rc_callbacks, volume_change_cb, pavrc_resp->reg_notif.param.volume,ctype)
1543 case AVRC_PDU_SET_ABSOLUTE_VOLUME:
1545 BTIF_TRACE_DEBUG("%s Set absolute volume change event received: volume %d,ctype %d",
1546 __FUNCTION__, pavrc_resp->volume.volume,ctype);
1547 if (AVRC_RSP_ACCEPT==ctype)
1548 btif_rc_cb.rc_volume=pavrc_resp->volume.volume;
1549 HAL_CBACK(bt_rc_callbacks,volume_change_cb,pavrc_resp->volume.volume,ctype)
1559 /************************************************************************************
1560 ** AVRCP API Functions
1561 ************************************************************************************/
1563 /*******************************************************************************
1567 ** Description Initializes the AVRC interface
1569 ** Returns bt_status_t
1571 *******************************************************************************/
1572 static bt_status_t init(btrc_callbacks_t* callbacks )
1574 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1575 bt_status_t result = BT_STATUS_SUCCESS;
1577 if (bt_rc_callbacks)
1578 return BT_STATUS_DONE;
1580 bt_rc_callbacks = callbacks;
1581 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1582 btif_rc_cb.rc_vol_label=MAX_LABEL;
1583 btif_rc_cb.rc_volume=MAX_VOLUME;
1589 /*******************************************************************************
1591 ** Function init_ctrl
1593 ** Description Initializes the AVRC interface
1595 ** Returns bt_status_t
1597 *******************************************************************************/
1598 static bt_status_t init_ctrl(btrc_ctrl_callbacks_t* callbacks )
1600 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
1601 bt_status_t result = BT_STATUS_SUCCESS;
1603 if (bt_rc_ctrl_callbacks)
1604 return BT_STATUS_DONE;
1606 bt_rc_ctrl_callbacks = callbacks;
1607 memset (&btif_rc_cb, 0, sizeof(btif_rc_cb));
1608 btif_rc_cb.rc_vol_label=MAX_LABEL;
1609 btif_rc_cb.rc_volume=MAX_VOLUME;
1615 static void rc_ctrl_procedure_complete ()
1617 if (btif_rc_cb.rc_procedure_complete == TRUE)
1621 btif_rc_cb.rc_procedure_complete = TRUE;
1622 UINT32 attr_list[] = {
1623 AVRC_MEDIA_ATTR_ID_TITLE,
1624 AVRC_MEDIA_ATTR_ID_ARTIST,
1625 AVRC_MEDIA_ATTR_ID_ALBUM,
1626 AVRC_MEDIA_ATTR_ID_TRACK_NUM,
1627 AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
1628 AVRC_MEDIA_ATTR_ID_GENRE,
1629 AVRC_MEDIA_ATTR_ID_PLAYING_TIME
1631 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
1634 /***************************************************************************
1636 ** Function get_play_status_rsp
1638 ** Description Returns the current play status.
1639 ** This method is called in response to
1640 ** GetPlayStatus request.
1642 ** Returns bt_status_t
1644 ***************************************************************************/
1645 static bt_status_t get_play_status_rsp(btrc_play_status_t play_status, uint32_t song_len,
1648 tAVRC_RESPONSE avrc_rsp;
1650 memset(&(avrc_rsp.get_play_status), 0, sizeof(tAVRC_GET_PLAY_STATUS_RSP));
1651 avrc_rsp.get_play_status.song_len = song_len;
1652 avrc_rsp.get_play_status.song_pos = song_pos;
1653 avrc_rsp.get_play_status.play_status = play_status;
1655 avrc_rsp.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
1656 avrc_rsp.get_play_status.opcode = opcode_from_pdu(AVRC_PDU_GET_PLAY_STATUS);
1657 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1658 /* Send the response */
1659 SEND_METAMSG_RSP(IDX_GET_PLAY_STATUS_RSP, &avrc_rsp);
1660 return BT_STATUS_SUCCESS;
1663 /***************************************************************************
1665 ** Function get_element_attr_rsp
1667 ** Description Returns the current songs' element attributes
1670 ** Returns bt_status_t
1672 ***************************************************************************/
1673 static bt_status_t get_element_attr_rsp(uint8_t num_attr, btrc_element_attr_val_t *p_attrs)
1675 tAVRC_RESPONSE avrc_rsp;
1677 tAVRC_ATTR_ENTRY element_attrs[BTRC_MAX_ELEM_ATTR_SIZE];
1679 memset(element_attrs, 0, sizeof(tAVRC_ATTR_ENTRY) * num_attr);
1683 avrc_rsp.get_play_status.status = AVRC_STS_BAD_PARAM;
1687 for (i=0; i<num_attr; i++) {
1688 element_attrs[i].attr_id = p_attrs[i].attr_id;
1689 element_attrs[i].name.charset_id = AVRC_CHARSET_ID_UTF8;
1690 element_attrs[i].name.str_len = (UINT16)strlen((char *)p_attrs[i].text);
1691 element_attrs[i].name.p_str = p_attrs[i].text;
1692 BTIF_TRACE_DEBUG("%s attr_id:0x%x, charset_id:0x%x, str_len:%d, str:%s",
1693 __FUNCTION__, (unsigned int)element_attrs[i].attr_id,
1694 element_attrs[i].name.charset_id, element_attrs[i].name.str_len,
1695 element_attrs[i].name.p_str);
1697 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1699 avrc_rsp.get_elem_attrs.num_attr = num_attr;
1700 avrc_rsp.get_elem_attrs.p_attrs = element_attrs;
1701 avrc_rsp.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
1702 avrc_rsp.get_elem_attrs.opcode = opcode_from_pdu(AVRC_PDU_GET_ELEMENT_ATTR);
1703 /* Send the response */
1704 SEND_METAMSG_RSP(IDX_GET_ELEMENT_ATTR_RSP, &avrc_rsp);
1705 return BT_STATUS_SUCCESS;
1708 /***************************************************************************
1710 ** Function register_notification_rsp
1712 ** Description Response to the register notification request.
1715 ** Returns bt_status_t
1717 ***************************************************************************/
1718 static bt_status_t register_notification_rsp(btrc_event_id_t event_id,
1719 btrc_notification_type_t type, btrc_register_notification_t *p_param)
1721 tAVRC_RESPONSE avrc_rsp;
1723 BTIF_TRACE_EVENT("## %s ## event_id:%s", __FUNCTION__, dump_rc_notification_event_id(event_id));
1724 if (btif_rc_cb.rc_notif[event_id-1].bNotify == FALSE)
1726 BTIF_TRACE_ERROR("Avrcp Event id not registered: event_id = %x", event_id);
1727 return BT_STATUS_NOT_READY;
1729 memset(&(avrc_rsp.reg_notif), 0, sizeof(tAVRC_REG_NOTIF_RSP));
1730 avrc_rsp.reg_notif.event_id = event_id;
1734 case BTRC_EVT_PLAY_STATUS_CHANGED:
1735 avrc_rsp.reg_notif.param.play_status = p_param->play_status;
1736 if (avrc_rsp.reg_notif.param.play_status == PLAY_STATUS_PLAYING)
1737 btif_av_clear_remote_suspend_flag();
1739 case BTRC_EVT_TRACK_CHANGE:
1740 memcpy(&(avrc_rsp.reg_notif.param.track), &(p_param->track), sizeof(btrc_uid_t));
1742 case BTRC_EVT_PLAY_POS_CHANGED:
1743 avrc_rsp.reg_notif.param.play_pos = p_param->song_pos;
1746 BTIF_TRACE_WARNING("%s : Unhandled event ID : 0x%x", __FUNCTION__, event_id);
1747 return BT_STATUS_UNHANDLED;
1750 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1751 avrc_rsp.reg_notif.opcode = opcode_from_pdu(AVRC_PDU_REGISTER_NOTIFICATION);
1752 avrc_rsp.get_play_status.status = AVRC_STS_NO_ERROR;
1754 /* Send the response. */
1755 send_metamsg_rsp(btif_rc_cb.rc_handle, btif_rc_cb.rc_notif[event_id-1].label,
1756 ((type == BTRC_NOTIFICATION_TYPE_INTERIM)?AVRC_CMD_NOTIF:AVRC_RSP_CHANGED), &avrc_rsp);
1757 return BT_STATUS_SUCCESS;
1760 /***************************************************************************
1762 ** Function set_volume
1764 ** Description Send current volume setting to remote side.
1765 ** Support limited to SetAbsoluteVolume
1766 ** This can be enhanced to support Relative Volume (AVRCP 1.0).
1767 ** With RelateVolume, we will send VOLUME_UP/VOLUME_DOWN
1768 ** as opposed to absolute volume level
1769 ** volume: Should be in the range 0-127. bit7 is reseved and cannot be set
1771 ** Returns bt_status_t
1773 ***************************************************************************/
1774 static bt_status_t set_volume(uint8_t volume)
1776 BTIF_TRACE_DEBUG("%s", __FUNCTION__);
1778 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1779 rc_transaction_t *p_transaction=NULL;
1781 if (btif_rc_cb.rc_volume==volume)
1783 status=BT_STATUS_DONE;
1784 BTIF_TRACE_ERROR("%s: volume value already set earlier: 0x%02x",__FUNCTION__, volume);
1788 if ((btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG) &&
1789 (btif_rc_cb.rc_features & BTA_AV_FEAT_ADV_CTRL))
1791 tAVRC_COMMAND avrc_cmd = {0};
1792 BT_HDR *p_msg = NULL;
1794 BTIF_TRACE_DEBUG("%s: Peer supports absolute volume. newVolume=%d", __FUNCTION__, volume);
1795 avrc_cmd.volume.opcode = AVRC_OP_VENDOR;
1796 avrc_cmd.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
1797 avrc_cmd.volume.status = AVRC_STS_NO_ERROR;
1798 avrc_cmd.volume.volume = volume;
1800 if (AVRC_BldCommand(&avrc_cmd, &p_msg) == AVRC_STS_NO_ERROR)
1802 bt_status_t tran_status=get_transaction(&p_transaction);
1803 if (BT_STATUS_SUCCESS == tran_status && NULL!=p_transaction)
1805 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
1806 __FUNCTION__,p_transaction->lbl);
1807 BTA_AvMetaCmd(btif_rc_cb.rc_handle,p_transaction->lbl, AVRC_CMD_CTRL, p_msg);
1808 status = BT_STATUS_SUCCESS;
1813 BTIF_TRACE_ERROR("%s: failed to obtain transaction details. status: 0x%02x",
1814 __FUNCTION__, tran_status);
1815 status = BT_STATUS_FAIL;
1820 BTIF_TRACE_ERROR("%s: failed to build absolute volume command. status: 0x%02x",
1821 __FUNCTION__, status);
1822 status = BT_STATUS_FAIL;
1826 status=BT_STATUS_NOT_READY;
1830 /***************************************************************************
1832 ** Function register_volumechange
1834 ** Description Register for volume change notification from remote side.
1838 ***************************************************************************/
1840 static void register_volumechange (UINT8 lbl)
1842 tAVRC_COMMAND avrc_cmd = {0};
1843 BT_HDR *p_msg = NULL;
1844 tAVRC_STS BldResp=AVRC_STS_BAD_CMD;
1845 rc_transaction_t *p_transaction=NULL;
1847 BTIF_TRACE_DEBUG("%s called with label:%d",__FUNCTION__,lbl);
1849 avrc_cmd.cmd.opcode=0x00;
1850 avrc_cmd.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
1851 avrc_cmd.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
1852 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
1853 avrc_cmd.reg_notif.param = 0;
1855 BldResp=AVRC_BldCommand(&avrc_cmd, &p_msg);
1856 if (AVRC_STS_NO_ERROR == BldResp && p_msg) {
1857 p_transaction = get_transaction_by_lbl(lbl);
1858 if (p_transaction != NULL) {
1859 BTA_AvMetaCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
1860 AVRC_CMD_NOTIF, p_msg);
1861 BTIF_TRACE_DEBUG("%s:BTA_AvMetaCmd called", __func__);
1864 BTIF_TRACE_ERROR("%s transaction not obtained with label: %d",
1868 BTIF_TRACE_ERROR("%s failed to build command:%d", __func__, BldResp);
1872 /***************************************************************************
1874 ** Function handle_rc_metamsg_rsp
1876 ** Description Handle RC metamessage response
1880 ***************************************************************************/
1881 static void handle_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
1883 tAVRC_RESPONSE avrc_response = {0};
1884 UINT8 scratch_buf[512] = {0};
1885 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
1887 if (AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode &&(AVRC_RSP_CHANGED==pmeta_msg->code
1888 || AVRC_RSP_INTERIM==pmeta_msg->code || AVRC_RSP_ACCEPT==pmeta_msg->code
1889 || AVRC_RSP_REJ==pmeta_msg->code || AVRC_RSP_NOT_IMPL==pmeta_msg->code))
1891 status=AVRC_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, sizeof(scratch_buf));
1892 BTIF_TRACE_DEBUG("%s: code %d,event ID %d,PDU %x,parsing status %d, label:%d",
1893 __FUNCTION__,pmeta_msg->code,avrc_response.reg_notif.event_id,avrc_response.reg_notif.pdu,
1894 status, pmeta_msg->label);
1896 if (status != AVRC_STS_NO_ERROR)
1898 if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1899 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1900 && btif_rc_cb.rc_vol_label==pmeta_msg->label)
1902 btif_rc_cb.rc_vol_label=MAX_LABEL;
1903 release_transaction(btif_rc_cb.rc_vol_label);
1905 else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1907 release_transaction(pmeta_msg->label);
1911 else if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1912 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1913 && btif_rc_cb.rc_vol_label!=pmeta_msg->label)
1915 // Just discard the message, if the device sends back with an incorrect label
1916 BTIF_TRACE_DEBUG("%s:Discarding register notfn in rsp.code: %d and label %d",
1917 __FUNCTION__, pmeta_msg->code, pmeta_msg->label);
1923 BTIF_TRACE_DEBUG("%s:Received vendor dependent in adv ctrl rsp. code: %d len: %d. Not processing it.",
1924 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
1928 if (AVRC_PDU_REGISTER_NOTIFICATION==avrc_response.rsp.pdu
1929 && AVRC_EVT_VOLUME_CHANGE==avrc_response.reg_notif.event_id
1930 && AVRC_RSP_CHANGED==pmeta_msg->code)
1932 /* re-register for volume change notification */
1933 // Do not re-register for rejected case, as it might get into endless loop
1934 register_volumechange(btif_rc_cb.rc_vol_label);
1936 else if (AVRC_PDU_SET_ABSOLUTE_VOLUME==avrc_response.rsp.pdu)
1938 /* free up the label here */
1939 release_transaction(pmeta_msg->label);
1942 BTIF_TRACE_EVENT("%s: Passing received metamsg response to app. pdu: %s",
1943 __FUNCTION__, dump_rc_pdu(avrc_response.pdu));
1944 btif_rc_upstreams_rsp_evt((uint16_t)avrc_response.rsp.pdu, &avrc_response, pmeta_msg->code,
1948 #if (AVRC_CTLR_INCLUDED == TRUE)
1949 /***************************************************************************
1951 ** Function iterate_supported_event_list_for_interim_rsp
1953 ** Description iterator callback function to match the event and handle
1955 ** Returns true to continue iterating, false to stop
1957 ***************************************************************************/
1958 bool iterate_supported_event_list_for_interim_rsp(void *data, void *cb_data)
1961 btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1963 p_event_id = (UINT8*)cb_data;
1965 if (p_event->event_id == *p_event_id)
1967 p_event->status = eINTERIM;
1973 /***************************************************************************
1975 ** Function iterate_supported_event_list_for_timeout
1977 ** Description Iterator callback function for timeout handling.
1978 ** As part of the failure handling, it releases the
1979 ** transaction label and removes the event from list,
1980 ** this event will not be requested again during
1981 ** the lifetime of the connection.
1982 ** Returns false to stop iterating, true to continue
1984 ***************************************************************************/
1985 bool iterate_supported_event_list_for_timeout(void *data, void *cb_data)
1988 btif_rc_supported_event_t *p_event = (btif_rc_supported_event_t *)data;
1990 label = (*(UINT8*)cb_data) & 0xFF;
1992 if (p_event->label == label)
1994 list_remove(btif_rc_cb.rc_supported_event_list, p_event);
2000 /***************************************************************************
2002 ** Function rc_notification_interim_timout
2004 ** Description Interim response timeout handler.
2005 ** Runs the iterator to check and clear the timed out event.
2006 ** Proceeds to register for the unregistered events.
2009 ***************************************************************************/
2010 static void rc_notification_interim_timout (UINT8 label)
2014 list_foreach(btif_rc_cb.rc_supported_event_list,
2015 iterate_supported_event_list_for_timeout, &label);
2016 /* Timeout happened for interim response for the registered event,
2017 * check if there are any pending for registration
2019 node = list_begin(btif_rc_cb.rc_supported_event_list);
2020 while (node != NULL)
2022 btif_rc_supported_event_t *p_event;
2024 p_event = (btif_rc_supported_event_t *)list_node(node);
2025 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2027 register_for_event_notification(p_event);
2030 node = list_next (node);
2032 /* Todo. Need to initiate application settings query if this
2033 * is the last event registration.
2037 /***************************************************************************
2039 ** Function btif_rc_status_cmd_timeout_handler
2041 ** Description RC status command timeout handler (Runs in BTIF context).
2044 ***************************************************************************/
2045 static void btif_rc_status_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2048 btif_rc_timer_context_t *p_context;
2049 tAVRC_RESPONSE avrc_response = {0};
2050 tBTA_AV_META_MSG meta_msg;
2052 p_context = (btif_rc_timer_context_t *)data;
2053 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2054 meta_msg.rc_handle = btif_rc_cb.rc_handle;
2056 switch (p_context->rc_status_cmd.pdu_id) {
2057 case AVRC_PDU_REGISTER_NOTIFICATION:
2058 rc_notification_interim_timout(p_context->rc_status_cmd.label);
2061 case AVRC_PDU_GET_CAPABILITIES:
2062 avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2063 handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2066 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
2067 avrc_response.list_app_attr.status = BTIF_RC_STS_TIMEOUT;
2068 handle_app_attr_response(&meta_msg, &avrc_response.list_app_attr);
2071 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
2072 avrc_response.list_app_values.status = BTIF_RC_STS_TIMEOUT;
2073 handle_app_val_response(&meta_msg, &avrc_response.list_app_values);
2076 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
2077 avrc_response.get_cur_app_val.status = BTIF_RC_STS_TIMEOUT;
2078 handle_app_cur_val_response(&meta_msg, &avrc_response.get_cur_app_val);
2081 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
2082 avrc_response.get_app_attr_txt.status = BTIF_RC_STS_TIMEOUT;
2083 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_attr_txt);
2086 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
2087 avrc_response.get_app_val_txt.status = BTIF_RC_STS_TIMEOUT;
2088 handle_app_attr_txt_response(&meta_msg, &avrc_response.get_app_val_txt);
2091 case AVRC_PDU_GET_ELEMENT_ATTR:
2092 avrc_response.get_elem_attrs.status = BTIF_RC_STS_TIMEOUT;
2093 handle_get_elem_attr_response(&meta_msg, &avrc_response.get_elem_attrs);
2096 case AVRC_PDU_GET_PLAY_STATUS:
2097 avrc_response.get_caps.status = BTIF_RC_STS_TIMEOUT;
2098 handle_get_capability_response(&meta_msg, &avrc_response.get_caps);
2101 release_transaction(p_context->rc_status_cmd.label);
2104 /***************************************************************************
2106 ** Function btif_rc_status_cmd_timer_timeout
2108 ** Description RC status command timeout callback.
2109 ** This is called from BTU context and switches to BTIF
2110 ** context to handle the timeout events
2113 ***************************************************************************/
2114 static void btif_rc_status_cmd_timer_timeout(void *data)
2116 btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2118 btif_transfer_context(btif_rc_status_cmd_timeout_handler, 0,
2119 (char *)p_data, sizeof(btif_rc_timer_context_t),
2123 /***************************************************************************
2125 ** Function btif_rc_control_cmd_timeout_handler
2127 ** Description RC control command timeout handler (Runs in BTIF context).
2130 ***************************************************************************/
2131 static void btif_rc_control_cmd_timeout_handler(UNUSED_ATTR uint16_t event,
2134 btif_rc_timer_context_t *p_context = (btif_rc_timer_context_t *)data;
2135 tAVRC_RESPONSE avrc_response = {0};
2136 tBTA_AV_META_MSG meta_msg;
2138 memset(&meta_msg, 0, sizeof(tBTA_AV_META_MSG));
2139 meta_msg.rc_handle = btif_rc_cb.rc_handle;
2141 switch (p_context->rc_control_cmd.pdu_id) {
2142 case AVRC_PDU_SET_PLAYER_APP_VALUE:
2143 avrc_response.set_app_val.status = BTIF_RC_STS_TIMEOUT;
2144 handle_set_app_attr_val_response(&meta_msg,
2145 &avrc_response.set_app_val);
2148 release_transaction(p_context->rc_control_cmd.label);
2151 /***************************************************************************
2153 ** Function btif_rc_control_cmd_timer_timeout
2155 ** Description RC control command timeout callback.
2156 ** This is called from BTU context and switches to BTIF
2157 ** context to handle the timeout events
2160 ***************************************************************************/
2161 static void btif_rc_control_cmd_timer_timeout(void *data)
2163 btif_rc_timer_context_t *p_data = (btif_rc_timer_context_t *)data;
2165 btif_transfer_context(btif_rc_control_cmd_timeout_handler, 0,
2166 (char *)p_data, sizeof(btif_rc_timer_context_t),
2170 /***************************************************************************
2172 ** Function btif_rc_play_status_timeout_handler
2174 ** Description RC play status timeout handler (Runs in BTIF context).
2177 ***************************************************************************/
2178 static void btif_rc_play_status_timeout_handler(UNUSED_ATTR uint16_t event,
2179 UNUSED_ATTR char *p_data)
2181 get_play_status_cmd();
2182 rc_start_play_status_timer();
2185 /***************************************************************************
2187 ** Function btif_rc_play_status_timer_timeout
2189 ** Description RC play status timeout callback.
2190 ** This is called from BTU context and switches to BTIF
2191 ** context to handle the timeout events
2194 ***************************************************************************/
2195 static void btif_rc_play_status_timer_timeout(UNUSED_ATTR void *data)
2197 btif_transfer_context(btif_rc_play_status_timeout_handler, 0, 0, 0, NULL);
2200 /***************************************************************************
2202 ** Function rc_start_play_status_timer
2204 ** Description Helper function to start the timer to fetch play status.
2207 ***************************************************************************/
2208 static void rc_start_play_status_timer(void)
2210 /* Start the Play status timer only if it is not started */
2211 if (!alarm_is_scheduled(btif_rc_cb.rc_play_status_timer)) {
2212 if (btif_rc_cb.rc_play_status_timer == NULL) {
2213 btif_rc_cb.rc_play_status_timer =
2214 alarm_new("btif_rc.rc_play_status_timer");
2216 alarm_set_on_queue(btif_rc_cb.rc_play_status_timer,
2217 BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2218 btif_rc_play_status_timer_timeout, NULL,
2219 btu_general_alarm_queue);
2223 /***************************************************************************
2225 ** Function rc_stop_play_status_timer
2227 ** Description Helper function to stop the play status timer.
2230 ***************************************************************************/
2231 void rc_stop_play_status_timer()
2233 if (btif_rc_cb.rc_play_status_timer != NULL)
2234 alarm_cancel(btif_rc_cb.rc_play_status_timer);
2237 /***************************************************************************
2239 ** Function register_for_event_notification
2241 ** Description Helper function registering notification events
2242 ** sets an interim response timeout to handle if the remote
2243 ** does not respond.
2246 ***************************************************************************/
2247 static void register_for_event_notification(btif_rc_supported_event_t *p_event)
2250 rc_transaction_t *p_transaction;
2252 status = get_transaction(&p_transaction);
2253 if (status == BT_STATUS_SUCCESS)
2255 btif_rc_timer_context_t *p_context = &p_transaction->txn_timer_context;
2257 status = register_notification_cmd (p_transaction->lbl, p_event->event_id, 0);
2258 if (status != BT_STATUS_SUCCESS)
2260 BTIF_TRACE_ERROR("%s Error in Notification registration %d",
2261 __FUNCTION__, status);
2262 release_transaction (p_transaction->lbl);
2265 p_event->label = p_transaction->lbl;
2266 p_event->status = eREGISTERED;
2267 p_context->rc_status_cmd.label = p_transaction->lbl;
2268 p_context->rc_status_cmd.pdu_id = AVRC_PDU_REGISTER_NOTIFICATION;
2270 alarm_free(p_transaction->txn_timer);
2271 p_transaction->txn_timer =
2272 alarm_new("btif_rc.status_command_txn_timer");
2273 alarm_set_on_queue(p_transaction->txn_timer,
2274 BTIF_TIMEOUT_RC_INTERIM_RSP_MS,
2275 btif_rc_status_cmd_timer_timeout, p_context,
2276 btu_general_alarm_queue);
2280 BTIF_TRACE_ERROR("%s Error No more Transaction label %d",
2281 __FUNCTION__, status);
2285 static void start_status_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2287 btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2288 p_context->rc_status_cmd.label = p_txn->lbl;
2289 p_context->rc_status_cmd.pdu_id = pdu_id;
2291 alarm_free(p_txn->txn_timer);
2292 p_txn->txn_timer = alarm_new("btif_rc.status_command_txn_timer");
2293 alarm_set_on_queue(p_txn->txn_timer, BTIF_TIMEOUT_RC_STATUS_CMD_MS,
2294 btif_rc_status_cmd_timer_timeout, p_context,
2295 btu_general_alarm_queue);
2298 static void start_control_command_timer(UINT8 pdu_id, rc_transaction_t *p_txn)
2300 btif_rc_timer_context_t *p_context = &p_txn->txn_timer_context;
2301 p_context->rc_control_cmd.label = p_txn->lbl;
2302 p_context->rc_control_cmd.pdu_id = pdu_id;
2304 alarm_free(p_txn->txn_timer);
2305 p_txn->txn_timer = alarm_new("btif_rc.control_command_txn_timer");
2306 alarm_set_on_queue(p_txn->txn_timer,
2307 BTIF_TIMEOUT_RC_CONTROL_CMD_MS,
2308 btif_rc_control_cmd_timer_timeout, p_context,
2309 btu_general_alarm_queue);
2312 /***************************************************************************
2314 ** Function handle_get_capability_response
2316 ** Description Handles the get_cap_response to populate company id info
2317 ** and query the supported events.
2318 ** Initiates Notification registration for events supported
2321 ***************************************************************************/
2322 static void handle_get_capability_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CAPS_RSP *p_rsp)
2326 /* Todo: Do we need to retry on command timeout */
2327 if (p_rsp->status != AVRC_STS_NO_ERROR)
2329 BTIF_TRACE_ERROR("%s Error capability response 0x%02X",
2330 __FUNCTION__, p_rsp->status);
2334 if (p_rsp->capability_id == AVRC_CAP_EVENTS_SUPPORTED)
2336 btif_rc_supported_event_t *p_event;
2338 /* Todo: Check if list can be active when we hit here */
2339 btif_rc_cb.rc_supported_event_list = list_new(osi_free);
2340 for (xx = 0; xx < p_rsp->count; xx++)
2342 /* Skip registering for Play position change notification */
2343 if ((p_rsp->param.event_id[xx] == AVRC_EVT_PLAY_STATUS_CHANGE)||
2344 (p_rsp->param.event_id[xx] == AVRC_EVT_TRACK_CHANGE)||
2345 (p_rsp->param.event_id[xx] == AVRC_EVT_APP_SETTING_CHANGE))
2347 p_event = (btif_rc_supported_event_t *)osi_malloc(sizeof(btif_rc_supported_event_t));
2348 p_event->event_id = p_rsp->param.event_id[xx];
2349 p_event->status = eNOT_REGISTERED;
2350 list_append(btif_rc_cb.rc_supported_event_list, p_event);
2353 p_event = list_front(btif_rc_cb.rc_supported_event_list);
2354 if (p_event != NULL)
2356 register_for_event_notification(p_event);
2359 else if (p_rsp->capability_id == AVRC_CAP_COMPANY_ID)
2361 getcapabilities_cmd (AVRC_CAP_EVENTS_SUPPORTED);
2362 BTIF_TRACE_EVENT("%s AVRC_CAP_COMPANY_ID: ", __FUNCTION__);
2363 for (xx = 0; xx < p_rsp->count; xx++)
2365 BTIF_TRACE_EVENT("%s : %d", __FUNCTION__, p_rsp->param.company_id[xx]);
2370 bool rc_is_track_id_valid (tAVRC_UID uid)
2372 tAVRC_UID invalid_uid = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
2374 if (memcmp(uid, invalid_uid, sizeof(tAVRC_UID)) == 0)
2384 /***************************************************************************
2386 ** Function handle_notification_response
2388 ** Description Main handler for notification responses to registered events
2389 ** 1. Register for unregistered event(in interim response path)
2390 ** 2. After registering for all supported events, start
2391 ** retrieving application settings and values
2392 ** 3. Reregister for events on getting changed response
2393 ** 4. Run play status timer for getting position when the
2394 ** status changes to playing
2395 ** 5. Get the Media details when the track change happens
2396 ** or track change interim response is received with
2398 ** 6. HAL callback for play status change and application
2402 ***************************************************************************/
2403 static void handle_notification_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_REG_NOTIF_RSP *p_rsp)
2405 bt_bdaddr_t rc_addr;
2406 UINT32 attr_list[] = {
2407 AVRC_MEDIA_ATTR_ID_TITLE,
2408 AVRC_MEDIA_ATTR_ID_ARTIST,
2409 AVRC_MEDIA_ATTR_ID_ALBUM,
2410 AVRC_MEDIA_ATTR_ID_TRACK_NUM,
2411 AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
2412 AVRC_MEDIA_ATTR_ID_GENRE,
2413 AVRC_MEDIA_ATTR_ID_PLAYING_TIME
2417 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2419 if (pmeta_msg->code == AVRC_RSP_INTERIM)
2421 btif_rc_supported_event_t *p_event;
2424 BTIF_TRACE_DEBUG("%s Interim response : 0x%2X ", __FUNCTION__, p_rsp->event_id);
2425 switch (p_rsp->event_id)
2427 case AVRC_EVT_PLAY_STATUS_CHANGE:
2428 /* Start timer to get play status periodically
2429 * if the play state is playing.
2431 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2433 rc_start_play_status_timer();
2435 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2436 &rc_addr, p_rsp->param.play_status);
2439 case AVRC_EVT_TRACK_CHANGE:
2440 if (rc_is_track_id_valid (p_rsp->param.track) != true)
2446 UINT8 *p_data = p_rsp->param.track;
2447 /* Update the UID for current track
2448 * Attributes will be fetched after the AVRCP procedure
2450 BE_STREAM_TO_UINT64(btif_rc_cb.rc_playing_uid, p_data);
2454 case AVRC_EVT_APP_SETTING_CHANGE:
2457 case AVRC_EVT_NOW_PLAYING_CHANGE:
2460 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2463 case AVRC_EVT_ADDR_PLAYER_CHANGE:
2466 case AVRC_EVT_UIDS_CHANGE:
2469 case AVRC_EVT_TRACK_REACHED_END:
2470 case AVRC_EVT_TRACK_REACHED_START:
2471 case AVRC_EVT_PLAY_POS_CHANGED:
2472 case AVRC_EVT_BATTERY_STATUS_CHANGE:
2473 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2475 BTIF_TRACE_ERROR("%s Unhandled interim response 0x%2X", __FUNCTION__,
2479 list_foreach(btif_rc_cb.rc_supported_event_list,
2480 iterate_supported_event_list_for_interim_rsp,
2483 node = list_begin(btif_rc_cb.rc_supported_event_list);
2484 while (node != NULL)
2486 p_event = (btif_rc_supported_event_t *)list_node(node);
2487 if ((p_event != NULL) && (p_event->status == eNOT_REGISTERED))
2489 register_for_event_notification(p_event);
2492 node = list_next (node);
2495 /* Registered for all events, we can request application settings */
2496 if ((p_event == NULL) && (btif_rc_cb.rc_app_settings.query_started == false))
2498 /* we need to do this only if remote TG supports
2499 * player application settings
2501 btif_rc_cb.rc_app_settings.query_started = TRUE;
2502 if (btif_rc_cb.rc_features & BTA_AV_FEAT_APP_SETTING)
2504 list_player_app_setting_attrib_cmd();
2508 BTIF_TRACE_DEBUG("%s App setting not supported, complete procedure", __FUNCTION__);
2509 rc_ctrl_procedure_complete();
2513 else if (pmeta_msg->code == AVRC_RSP_CHANGED)
2515 btif_rc_supported_event_t *p_event;
2518 BTIF_TRACE_DEBUG("%s Notification completed : 0x%2X ", __FUNCTION__,
2521 node = list_begin(btif_rc_cb.rc_supported_event_list);
2522 while (node != NULL)
2524 p_event = (btif_rc_supported_event_t *)list_node(node);
2525 if ((p_event != NULL) && (p_event->event_id == p_rsp->event_id))
2527 p_event->status = eNOT_REGISTERED;
2528 register_for_event_notification(p_event);
2531 node = list_next (node);
2534 switch (p_rsp->event_id)
2536 case AVRC_EVT_PLAY_STATUS_CHANGE:
2537 /* Start timer to get play status periodically
2538 * if the play state is playing.
2540 if (p_rsp->param.play_status == AVRC_PLAYSTATE_PLAYING)
2542 rc_start_play_status_timer();
2546 rc_stop_play_status_timer();
2548 HAL_CBACK(bt_rc_ctrl_callbacks, play_status_changed_cb,
2549 &rc_addr, p_rsp->param.play_status);
2552 case AVRC_EVT_TRACK_CHANGE:
2553 if (rc_is_track_id_valid (p_rsp->param.track) != true)
2557 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
2560 case AVRC_EVT_APP_SETTING_CHANGE:
2562 btrc_player_settings_t app_settings;
2565 app_settings.num_attr = p_rsp->param.player_setting.num_attr;
2566 for (xx = 0; xx < app_settings.num_attr; xx++)
2568 app_settings.attr_ids[xx] = p_rsp->param.player_setting.attr_id[xx];
2569 app_settings.attr_values[xx] = p_rsp->param.player_setting.attr_value[xx];
2571 HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2572 &rc_addr, &app_settings);
2576 case AVRC_EVT_NOW_PLAYING_CHANGE:
2579 case AVRC_EVT_AVAL_PLAYERS_CHANGE:
2582 case AVRC_EVT_ADDR_PLAYER_CHANGE:
2585 case AVRC_EVT_UIDS_CHANGE:
2588 case AVRC_EVT_TRACK_REACHED_END:
2589 case AVRC_EVT_TRACK_REACHED_START:
2590 case AVRC_EVT_PLAY_POS_CHANGED:
2591 case AVRC_EVT_BATTERY_STATUS_CHANGE:
2592 case AVRC_EVT_SYSTEM_STATUS_CHANGE:
2594 BTIF_TRACE_ERROR("%s Unhandled completion response 0x%2X",
2595 __FUNCTION__, p_rsp->event_id);
2601 /***************************************************************************
2603 ** Function handle_app_attr_response
2605 ** Description handles the the application attributes response and
2606 ** initiates procedure to fetch the attribute values
2609 ***************************************************************************/
2610 static void handle_app_attr_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_ATTR_RSP *p_rsp)
2614 if (p_rsp->status != AVRC_STS_NO_ERROR)
2616 BTIF_TRACE_ERROR("%s Error getting Player application settings: 0x%2X",
2617 __FUNCTION__, p_rsp->status);
2618 rc_ctrl_procedure_complete();
2622 for (xx = 0; xx < p_rsp->num_attr; xx++)
2626 if (p_rsp->attrs[xx] > AVRC_PLAYER_SETTING_LOW_MENU_EXT)
2628 st_index = btif_rc_cb.rc_app_settings.num_ext_attrs;
2629 btif_rc_cb.rc_app_settings.ext_attrs[st_index].attr_id = p_rsp->attrs[xx];
2630 btif_rc_cb.rc_app_settings.num_ext_attrs++;
2634 st_index = btif_rc_cb.rc_app_settings.num_attrs;
2635 btif_rc_cb.rc_app_settings.attrs[st_index].attr_id = p_rsp->attrs[xx];
2636 btif_rc_cb.rc_app_settings.num_attrs++;
2639 btif_rc_cb.rc_app_settings.attr_index = 0;
2640 btif_rc_cb.rc_app_settings.ext_attr_index = 0;
2641 btif_rc_cb.rc_app_settings.ext_val_index = 0;
2642 if (p_rsp->num_attr)
2644 list_player_app_setting_value_cmd (btif_rc_cb.rc_app_settings.attrs[0].attr_id);
2648 BTIF_TRACE_ERROR("%s No Player application settings found",
2653 /***************************************************************************
2655 ** Function handle_app_val_response
2657 ** Description handles the the attributes value response and if extended
2658 ** menu is available, it initiates query for the attribute
2659 ** text. If not, it initiates procedure to get the current
2660 ** attribute values and calls the HAL callback for provding
2661 ** application settings information.
2664 ***************************************************************************/
2665 static void handle_app_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_LIST_APP_VALUES_RSP *p_rsp)
2667 UINT8 xx, attr_index;
2668 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2669 btif_rc_player_app_settings_t *p_app_settings;
2670 bt_bdaddr_t rc_addr;
2672 /* Todo: Do we need to retry on command timeout */
2673 if (p_rsp->status != AVRC_STS_NO_ERROR)
2675 BTIF_TRACE_ERROR("%s Error fetching attribute values 0x%02X",
2676 __FUNCTION__, p_rsp->status);
2680 p_app_settings = &btif_rc_cb.rc_app_settings;
2681 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2683 if (p_app_settings->attr_index < p_app_settings->num_attrs)
2685 attr_index = p_app_settings->attr_index;
2686 p_app_settings->attrs[attr_index].num_val = p_rsp->num_val;
2687 for (xx = 0; xx < p_rsp->num_val; xx++)
2689 p_app_settings->attrs[attr_index].attr_val[xx] = p_rsp->vals[xx];
2692 p_app_settings->attr_index++;
2693 if (attr_index < p_app_settings->num_attrs)
2695 list_player_app_setting_value_cmd (p_app_settings->attrs[p_app_settings->attr_index].attr_id);
2697 else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2700 p_app_settings->ext_attr_index = 0;
2701 list_player_app_setting_value_cmd (p_app_settings->ext_attrs[attr_index].attr_id);
2705 for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2707 attrs[xx] = p_app_settings->attrs[xx].attr_id;
2709 get_player_app_setting_cmd (p_app_settings->num_attrs, attrs);
2710 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2711 p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
2714 else if (p_app_settings->ext_attr_index < p_app_settings->num_ext_attrs)
2716 attr_index = p_app_settings->ext_attr_index;
2717 p_app_settings->ext_attrs[attr_index].num_val = p_rsp->num_val;
2718 for (xx = 0; xx < p_rsp->num_val; xx++)
2720 p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val = p_rsp->vals[xx];
2723 p_app_settings->ext_attr_index++;
2724 if (attr_index < p_app_settings->num_ext_attrs)
2726 list_player_app_setting_value_cmd (p_app_settings->ext_attrs[p_app_settings->ext_attr_index].attr_id);
2730 UINT8 attr[AVRC_MAX_APP_ATTR_SIZE];
2733 for (xx = 0; xx < p_app_settings->num_ext_attrs; xx++)
2735 attr[xx] = p_app_settings->ext_attrs[xx].attr_id;
2737 get_player_app_setting_attr_text_cmd(attr, xx);
2742 /***************************************************************************
2744 ** Function handle_app_cur_val_response
2746 ** Description handles the the get attributes value response.
2750 ***************************************************************************/
2751 static void handle_app_cur_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_CUR_APP_VALUE_RSP *p_rsp)
2753 btrc_player_settings_t app_settings;
2754 bt_bdaddr_t rc_addr;
2757 /* Todo: Do we need to retry on command timeout */
2758 if (p_rsp->status != AVRC_STS_NO_ERROR)
2760 BTIF_TRACE_ERROR("%s Error fetching current settings: 0x%02X",
2761 __FUNCTION__, p_rsp->status);
2765 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2767 app_settings.num_attr = p_rsp->num_val;
2768 for (xx = 0; xx < app_settings.num_attr; xx++)
2770 app_settings.attr_ids[xx] = p_rsp->p_vals[xx].attr_id;
2771 app_settings.attr_values[xx] = p_rsp->p_vals[xx].attr_val;
2773 HAL_CBACK(bt_rc_ctrl_callbacks, playerapplicationsetting_changed_cb,
2774 &rc_addr, &app_settings);
2775 /* Application settings are fetched only once for initial values
2776 * initiate anything that follows after RC procedure.
2777 * Defer it if browsing is supported till players query
2779 rc_ctrl_procedure_complete ();
2780 osi_free_and_reset((void **)&p_rsp->p_vals);
2783 /***************************************************************************
2785 ** Function handle_app_attr_txt_response
2787 ** Description handles the the get attributes text response, if fails
2788 ** calls HAL callback with just normal settings and initiates
2789 ** query for current settings else initiates query for value text
2792 ***************************************************************************/
2793 static void handle_app_attr_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2796 UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2797 btif_rc_player_app_settings_t *p_app_settings;
2798 bt_bdaddr_t rc_addr;
2800 p_app_settings = &btif_rc_cb.rc_app_settings;
2801 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2803 /* Todo: Do we need to retry on command timeout */
2804 if (p_rsp->status != AVRC_STS_NO_ERROR)
2806 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2808 BTIF_TRACE_ERROR("%s Error fetching attribute text: 0x%02X",
2809 __FUNCTION__, p_rsp->status);
2810 /* Not able to fetch Text for extended Menu, skip the process
2811 * and cleanup used memory. Proceed to get the current settings
2812 * for standard attributes.
2814 p_app_settings->num_ext_attrs = 0;
2815 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2816 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2817 p_app_settings->ext_attr_index = 0;
2819 for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2821 attrs[xx] = p_app_settings->attrs[xx].attr_id;
2823 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2824 p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
2826 get_player_app_setting_cmd (xx, attrs);
2830 for (xx = 0; xx < p_rsp->num_attr; xx++)
2833 for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2835 if (p_app_settings->ext_attrs[x].attr_id == p_rsp->p_attrs[xx].attr_id)
2837 p_app_settings->ext_attrs[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2838 p_app_settings->ext_attrs[x].str_len = p_rsp->p_attrs[xx].str_len;
2839 p_app_settings->ext_attrs[x].p_str = p_rsp->p_attrs[xx].p_str;
2845 for (xx = 0; xx < p_app_settings->ext_attrs[0].num_val; xx++)
2847 vals[xx] = p_app_settings->ext_attrs[0].ext_attr_val[xx].val;
2849 get_player_app_setting_value_text_cmd(vals, xx);
2853 /***************************************************************************
2855 ** Function handle_app_attr_val_txt_response
2857 ** Description handles the the get attributes value text response, if fails
2858 ** calls HAL callback with just normal settings and initiates
2859 ** query for current settings
2862 ***************************************************************************/
2863 static void handle_app_attr_val_txt_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_APP_ATTR_TXT_RSP *p_rsp)
2865 UINT8 xx, attr_index;
2866 UINT8 vals[AVRC_MAX_APP_ATTR_SIZE];
2867 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2868 btif_rc_player_app_settings_t *p_app_settings;
2869 bt_bdaddr_t rc_addr;
2871 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2872 p_app_settings = &btif_rc_cb.rc_app_settings;
2874 /* Todo: Do we need to retry on command timeout */
2875 if (p_rsp->status != AVRC_STS_NO_ERROR)
2877 UINT8 attrs[AVRC_MAX_APP_ATTR_SIZE];
2879 BTIF_TRACE_ERROR("%s Error fetching attribute value text: 0x%02X",
2880 __FUNCTION__, p_rsp->status);
2882 /* Not able to fetch Text for extended Menu, skip the process
2883 * and cleanup used memory. Proceed to get the current settings
2884 * for standard attributes.
2886 p_app_settings->num_ext_attrs = 0;
2887 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2890 btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2892 for (x = 0; x < p_ext_attr->num_val; x++)
2893 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2894 p_ext_attr->num_val = 0;
2895 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2897 p_app_settings->ext_attr_index = 0;
2899 for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2901 attrs[xx] = p_app_settings->attrs[xx].attr_id;
2903 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2904 p_app_settings->num_attrs, &p_app_settings->attrs, 0, NULL);
2906 get_player_app_setting_cmd (xx, attrs);
2910 for (xx = 0; xx < p_rsp->num_attr; xx++)
2913 btrc_player_app_ext_attr_t *p_ext_attr;
2914 p_ext_attr = &p_app_settings->ext_attrs[p_app_settings->ext_val_index];
2915 for (x = 0; x < p_rsp->num_attr; x++)
2917 if (p_ext_attr->ext_attr_val[x].val == p_rsp->p_attrs[xx].attr_id)
2919 p_ext_attr->ext_attr_val[x].charset_id = p_rsp->p_attrs[xx].charset_id;
2920 p_ext_attr->ext_attr_val[x].str_len = p_rsp->p_attrs[xx].str_len;
2921 p_ext_attr->ext_attr_val[x].p_str = p_rsp->p_attrs[xx].p_str;
2926 p_app_settings->ext_val_index++;
2928 if (p_app_settings->ext_val_index < p_app_settings->num_ext_attrs)
2930 attr_index = p_app_settings->ext_val_index;
2931 for (xx = 0; xx < p_app_settings->ext_attrs[attr_index].num_val; xx++)
2933 vals[xx] = p_app_settings->ext_attrs[attr_index].ext_attr_val[xx].val;
2935 get_player_app_setting_value_text_cmd(vals, xx);
2941 for (xx = 0; xx < p_app_settings->num_attrs; xx++)
2943 attrs[xx] = p_app_settings->attrs[xx].attr_id;
2945 for (x = 0; x < p_app_settings->num_ext_attrs; x++)
2947 attrs[xx+x] = p_app_settings->ext_attrs[x].attr_id;
2949 HAL_CBACK (bt_rc_ctrl_callbacks, playerapplicationsetting_cb, &rc_addr,
2950 p_app_settings->num_attrs, &p_app_settings->attrs,
2951 p_app_settings->num_ext_attrs, &p_app_settings->ext_attrs);
2952 get_player_app_setting_cmd (xx + x, attrs);
2954 /* Free the application settings information after sending to
2957 for (xx = 0; xx < p_app_settings->ext_attr_index; xx++)
2960 btrc_player_app_ext_attr_t *p_ext_attr = &p_app_settings->ext_attrs[xx];
2962 for (x = 0; x < p_ext_attr->num_val; x++)
2963 osi_free_and_reset((void **)&p_ext_attr->ext_attr_val[x].p_str);
2964 p_ext_attr->num_val = 0;
2965 osi_free_and_reset((void **)&p_app_settings->ext_attrs[xx].p_str);
2967 p_app_settings->num_attrs = 0;
2971 /***************************************************************************
2973 ** Function handle_set_app_attr_val_response
2975 ** Description handles the the set attributes value response, if fails
2976 ** calls HAL callback to indicate the failure
2979 ***************************************************************************/
2980 static void handle_set_app_attr_val_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_RSP *p_rsp)
2982 uint8_t accepted = 0;
2983 bt_bdaddr_t rc_addr;
2985 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
2987 /* For timeout pmeta_msg will be NULL, else we need to
2988 * check if this is accepted by TG
2990 if (pmeta_msg && (pmeta_msg->code == AVRC_RSP_ACCEPT))
2994 HAL_CBACK(bt_rc_ctrl_callbacks, setplayerappsetting_rsp_cb, &rc_addr, accepted);
2997 /***************************************************************************
2999 ** Function handle_get_elem_attr_response
3001 ** Description handles the the element attributes response, calls
3002 ** HAL callback to update track change information.
3005 ***************************************************************************/
3006 static void handle_get_elem_attr_response (tBTA_AV_META_MSG *pmeta_msg,
3007 tAVRC_GET_ELEM_ATTRS_RSP *p_rsp)
3009 if (p_rsp->status == AVRC_STS_NO_ERROR) {
3010 bt_bdaddr_t rc_addr;
3011 size_t buf_size = p_rsp->num_attr * sizeof(btrc_element_attr_val_t);
3012 btrc_element_attr_val_t *p_attr =
3013 (btrc_element_attr_val_t *)osi_calloc(buf_size);
3015 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3017 for (int i = 0; i < p_rsp->num_attr; i++) {
3018 p_attr[i].attr_id = p_rsp->p_attrs[i].attr_id;
3019 /* Todo. Legth limit check to include null */
3020 if (p_rsp->p_attrs[i].name.str_len &&
3021 p_rsp->p_attrs[i].name.p_str) {
3022 memcpy(p_attr[i].text, p_rsp->p_attrs[i].name.p_str,
3023 p_rsp->p_attrs[i].name.str_len);
3024 osi_free_and_reset((void **)&p_rsp->p_attrs[i].name.p_str);
3027 HAL_CBACK(bt_rc_ctrl_callbacks, track_changed_cb,
3028 &rc_addr, p_rsp->num_attr, p_attr);
3030 } else if (p_rsp->status == BTIF_RC_STS_TIMEOUT) {
3031 /* Retry for timeout case, this covers error handling
3032 * for continuation failure also.
3034 UINT32 attr_list[] = {
3035 AVRC_MEDIA_ATTR_ID_TITLE,
3036 AVRC_MEDIA_ATTR_ID_ARTIST,
3037 AVRC_MEDIA_ATTR_ID_ALBUM,
3038 AVRC_MEDIA_ATTR_ID_TRACK_NUM,
3039 AVRC_MEDIA_ATTR_ID_NUM_TRACKS,
3040 AVRC_MEDIA_ATTR_ID_GENRE,
3041 AVRC_MEDIA_ATTR_ID_PLAYING_TIME
3043 get_element_attribute_cmd (AVRC_MAX_NUM_MEDIA_ATTR_ID, attr_list);
3045 BTIF_TRACE_ERROR("%s: Error in get element attr procedure %d",
3046 __func__, p_rsp->status);
3050 /***************************************************************************
3052 ** Function handle_get_playstatus_response
3054 ** Description handles the the play status response, calls
3055 ** HAL callback to update play position.
3058 ***************************************************************************/
3059 static void handle_get_playstatus_response (tBTA_AV_META_MSG *pmeta_msg, tAVRC_GET_PLAY_STATUS_RSP *p_rsp)
3061 bt_bdaddr_t rc_addr;
3063 bdcpy(rc_addr.address, btif_rc_cb.rc_addr);
3065 if (p_rsp->status == AVRC_STS_NO_ERROR)
3067 HAL_CBACK(bt_rc_ctrl_callbacks, play_position_changed_cb,
3068 &rc_addr, p_rsp->song_len, p_rsp->song_pos);
3072 BTIF_TRACE_ERROR("%s: Error in get play status procedure %d",
3073 __FUNCTION__, p_rsp->status);
3077 /***************************************************************************
3079 ** Function clear_cmd_timeout
3081 ** Description helper function to stop the command timeout timer
3084 ***************************************************************************/
3085 static void clear_cmd_timeout (UINT8 label)
3087 rc_transaction_t *p_txn;
3089 p_txn = get_transaction_by_lbl (label);
3092 BTIF_TRACE_ERROR("%s: Error in transaction label lookup", __FUNCTION__);
3096 if (p_txn->txn_timer != NULL)
3097 alarm_cancel(p_txn->txn_timer);
3100 /***************************************************************************
3102 ** Function handle_avk_rc_metamsg_rsp
3104 ** Description Handle RC metamessage response
3108 ***************************************************************************/
3109 static void handle_avk_rc_metamsg_rsp(tBTA_AV_META_MSG *pmeta_msg)
3111 tAVRC_RESPONSE avrc_response = {0};
3112 UINT8 scratch_buf[512] = {0};// this variable is unused
3116 BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d ", __FUNCTION__,
3117 pmeta_msg->p_msg->hdr.opcode, pmeta_msg->code);
3119 if ((AVRC_OP_VENDOR == pmeta_msg->p_msg->hdr.opcode)&&
3120 (pmeta_msg->code >= AVRC_RSP_NOT_IMPL)&&
3121 (pmeta_msg->code <= AVRC_RSP_INTERIM))
3123 status = AVRC_Ctrl_ParsResponse(pmeta_msg->p_msg, &avrc_response, scratch_buf, &buf_len);
3124 BTIF_TRACE_DEBUG("%s parse status %d pdu = %d rsp_status = %d",
3125 __FUNCTION__, status, avrc_response.pdu,
3126 pmeta_msg->p_msg->vendor.hdr.ctype);
3128 switch (avrc_response.pdu)
3130 case AVRC_PDU_REGISTER_NOTIFICATION:
3131 handle_notification_response(pmeta_msg, &avrc_response.reg_notif);
3132 if (pmeta_msg->code == AVRC_RSP_INTERIM)
3134 /* Don't free the transaction Id */
3135 clear_cmd_timeout (pmeta_msg->label);
3140 case AVRC_PDU_GET_CAPABILITIES:
3141 handle_get_capability_response(pmeta_msg, &avrc_response.get_caps);
3144 case AVRC_PDU_LIST_PLAYER_APP_ATTR:
3145 handle_app_attr_response(pmeta_msg, &avrc_response.list_app_attr);
3148 case AVRC_PDU_LIST_PLAYER_APP_VALUES:
3149 handle_app_val_response(pmeta_msg, &avrc_response.list_app_values);
3152 case AVRC_PDU_GET_CUR_PLAYER_APP_VALUE:
3153 handle_app_cur_val_response(pmeta_msg, &avrc_response.get_cur_app_val);
3156 case AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT:
3157 handle_app_attr_txt_response(pmeta_msg, &avrc_response.get_app_attr_txt);
3160 case AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT:
3161 handle_app_attr_val_txt_response(pmeta_msg, &avrc_response.get_app_val_txt);
3164 case AVRC_PDU_SET_PLAYER_APP_VALUE:
3165 handle_set_app_attr_val_response(pmeta_msg, &avrc_response.set_app_val);
3168 case AVRC_PDU_GET_ELEMENT_ATTR:
3169 handle_get_elem_attr_response(pmeta_msg, &avrc_response.get_elem_attrs);
3172 case AVRC_PDU_GET_PLAY_STATUS:
3173 handle_get_playstatus_response(pmeta_msg, &avrc_response.get_play_status);
3176 release_transaction(pmeta_msg->label);
3180 BTIF_TRACE_DEBUG("%s:Invalid Vendor Command code: %d len: %d. Not processing it.",
3181 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3186 /***************************************************************************
3188 ** Function handle_avk_rc_metamsg_cmd
3190 ** Description Handle RC metamessage response
3194 ***************************************************************************/
3195 static void handle_avk_rc_metamsg_cmd(tBTA_AV_META_MSG *pmeta_msg)
3197 tAVRC_COMMAND avrc_cmd = {0};
3198 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3199 BTIF_TRACE_DEBUG("%s opcode = %d rsp_code = %d ",__FUNCTION__,
3200 pmeta_msg->p_msg->hdr.opcode,pmeta_msg->code);
3201 if ((AVRC_OP_VENDOR==pmeta_msg->p_msg->hdr.opcode)&&
3202 (pmeta_msg->code <= AVRC_CMD_GEN_INQ))
3204 status = AVRC_Ctrl_ParsCommand(pmeta_msg->p_msg, &avrc_cmd);
3205 BTIF_TRACE_DEBUG("%s Received vendor command.code %d, PDU %d label %d",
3206 __FUNCTION__, pmeta_msg->code, avrc_cmd.pdu, pmeta_msg->label);
3208 if (status != AVRC_STS_NO_ERROR)
3211 BTIF_TRACE_WARNING("%s: Error in parsing received metamsg command. status: 0x%02x",
3212 __FUNCTION__, status);
3213 send_reject_response(pmeta_msg->rc_handle, pmeta_msg->label, avrc_cmd.pdu, status);
3217 if (avrc_cmd.pdu == AVRC_PDU_REGISTER_NOTIFICATION)
3219 UINT8 event_id = avrc_cmd.reg_notif.event_id;
3220 BTIF_TRACE_EVENT("%s:Register notification event_id: %s",
3221 __FUNCTION__, dump_rc_notification_event_id(event_id));
3223 else if (avrc_cmd.pdu == AVRC_PDU_SET_ABSOLUTE_VOLUME)
3225 BTIF_TRACE_EVENT("%s: Abs Volume Cmd Recvd", __FUNCTION__);
3227 btif_rc_ctrl_upstreams_rsp_cmd(avrc_cmd.pdu, &avrc_cmd, pmeta_msg->label);
3232 BTIF_TRACE_DEBUG("%s:Invalid Vendor Command code: %d len: %d. Not processing it.",
3233 __FUNCTION__, pmeta_msg->code, pmeta_msg->len);
3239 /***************************************************************************
3243 ** Description Closes the AVRC interface
3247 ***************************************************************************/
3248 static void cleanup()
3250 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3252 if (bt_rc_callbacks)
3254 bt_rc_callbacks = NULL;
3256 alarm_free(btif_rc_cb.rc_play_status_timer);
3257 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3259 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3262 /***************************************************************************
3264 ** Function cleanup_ctrl
3266 ** Description Closes the AVRC Controller interface
3270 ***************************************************************************/
3271 static void cleanup_ctrl()
3273 BTIF_TRACE_EVENT("## %s ##", __FUNCTION__);
3275 if (bt_rc_ctrl_callbacks)
3277 bt_rc_ctrl_callbacks = NULL;
3279 alarm_free(btif_rc_cb.rc_play_status_timer);
3280 memset(&btif_rc_cb, 0, sizeof(btif_rc_cb_t));
3282 BTIF_TRACE_EVENT("## %s ## completed", __FUNCTION__);
3285 /***************************************************************************
3287 ** Function getcapabilities_cmd
3289 ** Description GetCapabilties from Remote(Company_ID, Events_Supported)
3293 ***************************************************************************/
3294 static bt_status_t getcapabilities_cmd (uint8_t cap_id)
3296 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3297 rc_transaction_t *p_transaction = NULL;
3298 #if (AVRC_CTLR_INCLUDED == TRUE)
3299 BTIF_TRACE_DEBUG("%s: cap_id %d", __FUNCTION__, cap_id);
3301 bt_status_t tran_status=get_transaction(&p_transaction);
3302 if (BT_STATUS_SUCCESS != tran_status)
3303 return BT_STATUS_FAIL;
3305 tAVRC_COMMAND avrc_cmd = {0};
3306 BT_HDR *p_msg = NULL;
3307 avrc_cmd.get_caps.opcode = AVRC_OP_VENDOR;
3308 avrc_cmd.get_caps.capability_id = cap_id;
3309 avrc_cmd.get_caps.pdu = AVRC_PDU_GET_CAPABILITIES;
3310 avrc_cmd.get_caps.status = AVRC_STS_NO_ERROR;
3311 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3312 if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3314 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3315 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3316 __FUNCTION__,p_transaction->lbl);
3317 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3318 data_start, p_msg->len);
3319 status = BT_STATUS_SUCCESS;
3320 start_status_command_timer (AVRC_PDU_GET_CAPABILITIES, p_transaction);
3324 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3325 __FUNCTION__, status);
3329 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3334 /***************************************************************************
3336 ** Function list_player_app_setting_attrib_cmd
3338 ** Description Get supported List Player Attributes
3342 ***************************************************************************/
3343 static bt_status_t list_player_app_setting_attrib_cmd(void)
3345 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3346 rc_transaction_t *p_transaction = NULL;
3347 #if (AVRC_CTLR_INCLUDED == TRUE)
3348 BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3350 bt_status_t tran_status=get_transaction(&p_transaction);
3351 if (BT_STATUS_SUCCESS != tran_status)
3352 return BT_STATUS_FAIL;
3354 tAVRC_COMMAND avrc_cmd = {0};
3355 BT_HDR *p_msg = NULL;
3356 avrc_cmd.list_app_attr.opcode = AVRC_OP_VENDOR;
3357 avrc_cmd.list_app_attr.pdu = AVRC_PDU_LIST_PLAYER_APP_ATTR;
3358 avrc_cmd.list_app_attr.status = AVRC_STS_NO_ERROR;
3359 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3360 if ((status == AVRC_STS_NO_ERROR)&&(p_msg != NULL))
3362 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3363 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3364 __FUNCTION__,p_transaction->lbl);
3365 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3366 data_start, p_msg->len);
3367 status = BT_STATUS_SUCCESS;
3368 start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_ATTR, p_transaction);
3373 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3374 __FUNCTION__, status);
3378 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3383 /***************************************************************************
3385 ** Function list_player_app_setting_value_cmd
3387 ** Description Get values of supported Player Attributes
3391 ***************************************************************************/
3392 static bt_status_t list_player_app_setting_value_cmd(uint8_t attrib_id)
3394 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3395 rc_transaction_t *p_transaction=NULL;
3396 #if (AVRC_CTLR_INCLUDED == TRUE)
3397 BTIF_TRACE_DEBUG("%s: attrib_id %d", __FUNCTION__, attrib_id);
3399 bt_status_t tran_status=get_transaction(&p_transaction);
3400 if (BT_STATUS_SUCCESS != tran_status)
3401 return BT_STATUS_FAIL;
3403 tAVRC_COMMAND avrc_cmd = {0};
3404 BT_HDR *p_msg = NULL;
3405 avrc_cmd.list_app_values.attr_id = attrib_id;
3406 avrc_cmd.list_app_values.opcode = AVRC_OP_VENDOR;
3407 avrc_cmd.list_app_values.pdu = AVRC_PDU_LIST_PLAYER_APP_VALUES;
3408 avrc_cmd.list_app_values.status = AVRC_STS_NO_ERROR;
3409 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3410 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3412 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3413 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3414 __FUNCTION__,p_transaction->lbl);
3415 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3416 data_start, p_msg->len);
3417 status = BT_STATUS_SUCCESS;
3418 start_status_command_timer (AVRC_PDU_LIST_PLAYER_APP_VALUES, p_transaction);
3422 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3426 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3431 /***************************************************************************
3433 ** Function get_player_app_setting_cmd
3435 ** Description Get current values of Player Attributes
3439 ***************************************************************************/
3440 static bt_status_t get_player_app_setting_cmd(uint8_t num_attrib, uint8_t* attrib_ids)
3442 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3443 rc_transaction_t *p_transaction = NULL;
3445 #if (AVRC_CTLR_INCLUDED == TRUE)
3446 BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3448 bt_status_t tran_status=get_transaction(&p_transaction);
3449 if (BT_STATUS_SUCCESS != tran_status)
3450 return BT_STATUS_FAIL;
3452 tAVRC_COMMAND avrc_cmd = {0};
3453 BT_HDR *p_msg = NULL;
3454 avrc_cmd.get_cur_app_val.opcode = AVRC_OP_VENDOR;
3455 avrc_cmd.get_cur_app_val.status = AVRC_STS_NO_ERROR;
3456 avrc_cmd.get_cur_app_val.num_attr = num_attrib;
3457 avrc_cmd.get_cur_app_val.pdu = AVRC_PDU_GET_CUR_PLAYER_APP_VALUE;
3459 for (count = 0; count < num_attrib; count++)
3461 avrc_cmd.get_cur_app_val.attrs[count] = attrib_ids[count];
3463 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3464 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3466 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3467 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3468 __FUNCTION__,p_transaction->lbl);
3469 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_STATUS,
3470 data_start, p_msg->len);
3471 status = BT_STATUS_SUCCESS;
3472 start_status_command_timer (AVRC_PDU_GET_CUR_PLAYER_APP_VALUE, p_transaction);
3476 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3477 __FUNCTION__, status);
3481 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3486 /***************************************************************************
3488 ** Function change_player_app_setting
3490 ** Description Set current values of Player Attributes
3494 ***************************************************************************/
3495 static bt_status_t change_player_app_setting(bt_bdaddr_t *bd_addr, uint8_t num_attrib, uint8_t* attrib_ids, uint8_t* attrib_vals)
3497 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3498 rc_transaction_t *p_transaction = NULL;
3500 #if (AVRC_CTLR_INCLUDED == TRUE)
3501 BTIF_TRACE_DEBUG("%s: num attrib_id %d", __FUNCTION__, num_attrib);
3503 bt_status_t tran_status=get_transaction(&p_transaction);
3504 if (BT_STATUS_SUCCESS != tran_status)
3505 return BT_STATUS_FAIL;
3507 tAVRC_COMMAND avrc_cmd = {0};
3508 BT_HDR *p_msg = NULL;
3509 avrc_cmd.set_app_val.opcode = AVRC_OP_VENDOR;
3510 avrc_cmd.set_app_val.status = AVRC_STS_NO_ERROR;
3511 avrc_cmd.set_app_val.num_val = num_attrib;
3512 avrc_cmd.set_app_val.pdu = AVRC_PDU_SET_PLAYER_APP_VALUE;
3513 avrc_cmd.set_app_val.p_vals =
3514 (tAVRC_APP_SETTING *)osi_malloc(sizeof(tAVRC_APP_SETTING) * num_attrib);
3515 for (count = 0; count < num_attrib; count++)
3517 avrc_cmd.set_app_val.p_vals[count].attr_id = attrib_ids[count];
3518 avrc_cmd.set_app_val.p_vals[count].attr_val = attrib_vals[count];
3520 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3521 if ((status == AVRC_STS_NO_ERROR) && (p_msg != NULL))
3523 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3524 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3525 __FUNCTION__,p_transaction->lbl);
3526 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,AVRC_CMD_CTRL,
3527 data_start, p_msg->len);
3528 status = BT_STATUS_SUCCESS;
3529 start_control_command_timer (AVRC_PDU_SET_PLAYER_APP_VALUE, p_transaction);
3533 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3534 __FUNCTION__, status);
3537 osi_free_and_reset((void **)&avrc_cmd.set_app_val.p_vals);
3539 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3544 /***************************************************************************
3546 ** Function get_player_app_setting_attr_text_cmd
3548 ** Description Get text description for app attribute
3552 ***************************************************************************/
3553 static bt_status_t get_player_app_setting_attr_text_cmd (UINT8 *attrs, UINT8 num_attrs)
3555 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3556 rc_transaction_t *p_transaction = NULL;
3558 #if (AVRC_CTLR_INCLUDED == TRUE)
3559 tAVRC_COMMAND avrc_cmd = {0};
3560 BT_HDR *p_msg = NULL;
3561 bt_status_t tran_status;
3564 BTIF_TRACE_DEBUG("%s: num attrs %d", __FUNCTION__, num_attrs);
3566 tran_status = get_transaction(&p_transaction);
3567 if (BT_STATUS_SUCCESS != tran_status)
3568 return BT_STATUS_FAIL;
3570 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT;
3571 avrc_cmd.get_app_attr_txt.opcode = AVRC_OP_VENDOR;
3572 avrc_cmd.get_app_attr_txt.num_attr = num_attrs;
3574 for (count = 0; count < num_attrs; count++)
3576 avrc_cmd.get_app_attr_txt.attrs[count] = attrs[count];
3578 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3579 if (status == AVRC_STS_NO_ERROR)
3581 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3582 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3583 __FUNCTION__, p_transaction->lbl);
3584 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3585 AVRC_CMD_STATUS, data_start, p_msg->len);
3587 status = BT_STATUS_SUCCESS;
3588 start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_ATTR_TEXT, p_transaction);
3592 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x", __FUNCTION__, status);
3596 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3601 /***************************************************************************
3603 ** Function get_player_app_setting_val_text_cmd
3605 ** Description Get text description for app attribute values
3609 ***************************************************************************/
3610 static bt_status_t get_player_app_setting_value_text_cmd (UINT8 *vals, UINT8 num_vals)
3612 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3613 rc_transaction_t *p_transaction = NULL;
3615 #if (AVRC_CTLR_INCLUDED == TRUE)
3616 tAVRC_COMMAND avrc_cmd = {0};
3617 BT_HDR *p_msg = NULL;
3618 bt_status_t tran_status;
3621 BTIF_TRACE_DEBUG("%s: num_vals %d", __FUNCTION__, num_vals);
3623 tran_status = get_transaction(&p_transaction);
3624 if (BT_STATUS_SUCCESS != tran_status)
3625 return BT_STATUS_FAIL;
3627 avrc_cmd.pdu = AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT;
3628 avrc_cmd.get_app_val_txt.opcode = AVRC_OP_VENDOR;
3629 avrc_cmd.get_app_val_txt.num_val = num_vals;
3631 for (count = 0; count < num_vals; count++)
3633 avrc_cmd.get_app_val_txt.vals[count] = vals[count];
3635 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3636 if (status == AVRC_STS_NO_ERROR)
3638 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3639 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3640 __FUNCTION__, p_transaction->lbl);
3643 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3644 AVRC_CMD_STATUS, data_start, p_msg->len);
3645 status = BT_STATUS_SUCCESS;
3646 start_status_command_timer (AVRC_PDU_GET_PLAYER_APP_VALUE_TEXT, p_transaction);
3651 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3652 __FUNCTION__, status);
3656 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3661 /***************************************************************************
3663 ** Function register_notification_cmd
3665 ** Description Send Command to register for a Notification ID
3669 ***************************************************************************/
3670 static bt_status_t register_notification_cmd (UINT8 label, UINT8 event_id, UINT32 event_value)
3673 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3674 #if (AVRC_CTLR_INCLUDED == TRUE)
3675 tAVRC_COMMAND avrc_cmd = {0};
3676 BT_HDR *p_msg = NULL;
3680 BTIF_TRACE_DEBUG("%s: event_id %d event_value", __FUNCTION__, event_id, event_value);
3682 avrc_cmd.reg_notif.opcode = AVRC_OP_VENDOR;
3683 avrc_cmd.reg_notif.status = AVRC_STS_NO_ERROR;
3684 avrc_cmd.reg_notif.event_id = event_id;
3685 avrc_cmd.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3686 avrc_cmd.reg_notif.param = event_value;
3687 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3688 if (status == AVRC_STS_NO_ERROR)
3690 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3691 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3692 __FUNCTION__, label);
3695 BTA_AvVendorCmd(btif_rc_cb.rc_handle, label, AVRC_CMD_NOTIF,
3696 data_start, p_msg->len);
3697 status = BT_STATUS_SUCCESS;
3702 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3703 __FUNCTION__, status);
3707 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3712 /***************************************************************************
3714 ** Function get_element_attribute_cmd
3716 ** Description Get Element Attribute for attributeIds
3720 ***************************************************************************/
3721 static bt_status_t get_element_attribute_cmd (uint8_t num_attribute, uint32_t *p_attr_ids)
3723 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3724 rc_transaction_t *p_transaction=NULL;
3726 #if (AVRC_CTLR_INCLUDED == TRUE)
3727 tAVRC_COMMAND avrc_cmd = {0};
3728 BT_HDR *p_msg = NULL;
3729 bt_status_t tran_status;
3732 BTIF_TRACE_DEBUG("%s: num_attribute %d attribute_id %d",
3733 __FUNCTION__, num_attribute, p_attr_ids[0]);
3735 tran_status = get_transaction(&p_transaction);
3736 if (BT_STATUS_SUCCESS != tran_status)
3737 return BT_STATUS_FAIL;
3739 avrc_cmd.get_elem_attrs.opcode = AVRC_OP_VENDOR;
3740 avrc_cmd.get_elem_attrs.status = AVRC_STS_NO_ERROR;
3741 avrc_cmd.get_elem_attrs.num_attr = num_attribute;
3742 avrc_cmd.get_elem_attrs.pdu = AVRC_PDU_GET_ELEMENT_ATTR;
3743 for (count = 0; count < num_attribute; count++)
3745 avrc_cmd.get_elem_attrs.attrs[count] = p_attr_ids[count];
3748 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3749 if (status == AVRC_STS_NO_ERROR)
3751 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3752 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3753 __FUNCTION__, p_transaction->lbl);
3756 BTA_AvVendorCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3757 AVRC_CMD_STATUS, data_start, p_msg->len);
3758 status = BT_STATUS_SUCCESS;
3759 start_status_command_timer (AVRC_PDU_GET_ELEMENT_ATTR,
3765 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3766 __FUNCTION__, status);
3770 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3775 /***************************************************************************
3777 ** Function get_play_status_cmd
3779 ** Description Get Element Attribute for attributeIds
3783 ***************************************************************************/
3784 static bt_status_t get_play_status_cmd(void)
3786 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3787 rc_transaction_t *p_transaction = NULL;
3788 #if (AVRC_CTLR_INCLUDED == TRUE)
3789 tAVRC_COMMAND avrc_cmd = {0};
3790 BT_HDR *p_msg = NULL;
3791 bt_status_t tran_status;
3794 BTIF_TRACE_DEBUG("%s: ", __FUNCTION__);
3795 tran_status = get_transaction(&p_transaction);
3796 if (BT_STATUS_SUCCESS != tran_status)
3797 return BT_STATUS_FAIL;
3799 avrc_cmd.get_play_status.opcode = AVRC_OP_VENDOR;
3800 avrc_cmd.get_play_status.pdu = AVRC_PDU_GET_PLAY_STATUS;
3801 avrc_cmd.get_play_status.status = AVRC_STS_NO_ERROR;
3802 status = AVRC_BldCommand(&avrc_cmd, &p_msg);
3803 if (status == AVRC_STS_NO_ERROR)
3805 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3806 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3807 __FUNCTION__, p_transaction->lbl);
3810 BTA_AvVendorCmd(btif_rc_cb.rc_handle,p_transaction->lbl,
3811 AVRC_CMD_STATUS, data_start, p_msg->len);
3812 status = BT_STATUS_SUCCESS;
3813 start_status_command_timer (AVRC_PDU_GET_PLAY_STATUS, p_transaction);
3818 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3819 __FUNCTION__, status);
3823 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3829 /***************************************************************************
3831 ** Function set_volume_rsp
3833 ** Description Rsp for SetAbsoluteVolume Command
3837 ***************************************************************************/
3838 static bt_status_t set_volume_rsp(bt_bdaddr_t *bd_addr, uint8_t abs_vol, uint8_t label)
3840 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3841 #if (AVRC_CTLR_INCLUDED == TRUE)
3842 tAVRC_RESPONSE avrc_rsp;
3843 BT_HDR *p_msg = NULL;
3846 BTIF_TRACE_DEBUG("%s: abs_vol %d", __FUNCTION__, abs_vol);
3848 avrc_rsp.volume.opcode = AVRC_OP_VENDOR;
3849 avrc_rsp.volume.pdu = AVRC_PDU_SET_ABSOLUTE_VOLUME;
3850 avrc_rsp.volume.status = AVRC_STS_NO_ERROR;
3851 avrc_rsp.volume.volume = abs_vol;
3852 status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3853 if (status == AVRC_STS_NO_ERROR)
3855 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3856 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3857 __FUNCTION__, btif_rc_cb.rc_vol_label);
3860 BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3861 BTA_AV_RSP_ACCEPT, data_start, p_msg->len, 0);
3862 status = BT_STATUS_SUCCESS;
3867 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3868 __FUNCTION__, status);
3872 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3877 /***************************************************************************
3879 ** Function send_register_abs_vol_rsp
3881 ** Description Rsp for Notification of Absolute Volume
3885 ***************************************************************************/
3886 static bt_status_t volume_change_notification_rsp(bt_bdaddr_t *bd_addr, btrc_notification_type_t rsp_type,
3887 uint8_t abs_vol, uint8_t label)
3889 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3890 tAVRC_RESPONSE avrc_rsp;
3891 BT_HDR *p_msg = NULL;
3892 #if (AVRC_CTLR_INCLUDED == TRUE)
3893 BTIF_TRACE_DEBUG("%s: rsp_type %d abs_vol %d", __func__, rsp_type, abs_vol);
3896 avrc_rsp.reg_notif.opcode = AVRC_OP_VENDOR;
3897 avrc_rsp.reg_notif.pdu = AVRC_PDU_REGISTER_NOTIFICATION;
3898 avrc_rsp.reg_notif.status = AVRC_STS_NO_ERROR;
3899 avrc_rsp.reg_notif.param.volume = abs_vol;
3900 avrc_rsp.reg_notif.event_id = AVRC_EVT_VOLUME_CHANGE;
3902 status = AVRC_BldResponse(btif_rc_cb.rc_handle, &avrc_rsp, &p_msg);
3903 if (status == AVRC_STS_NO_ERROR) {
3904 BTIF_TRACE_DEBUG("%s msgreq being sent out with label %d",
3906 UINT8* data_start = (UINT8*)(p_msg + 1) + p_msg->offset;
3907 BTA_AvVendorRsp(btif_rc_cb.rc_handle, label,
3908 (rsp_type == BTRC_NOTIFICATION_TYPE_INTERIM) ?
3909 AVRC_RSP_INTERIM : AVRC_RSP_CHANGED,
3910 data_start, p_msg->len, 0);
3911 status = BT_STATUS_SUCCESS;
3913 BTIF_TRACE_ERROR("%s: failed to build command. status: 0x%02x",
3919 BTIF_TRACE_DEBUG("%s: feature not enabled", __func__);
3924 /***************************************************************************
3926 ** Function send_groupnavigation_cmd
3928 ** Description Send Pass-Through command
3932 ***************************************************************************/
3933 static bt_status_t send_groupnavigation_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code,
3936 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3937 #if (AVRC_CTLR_INCLUDED == TRUE)
3938 rc_transaction_t *p_transaction=NULL;
3939 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3940 key_code, key_state);
3942 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3944 bt_status_t tran_status = get_transaction(&p_transaction);
3945 if ((BT_STATUS_SUCCESS == tran_status) && (NULL != p_transaction)) {
3946 UINT8 buffer[AVRC_PASS_THRU_GROUP_LEN] = {0};
3947 UINT8* start = buffer;
3948 UINT24_TO_BE_STREAM(start, AVRC_CO_METADATA);
3950 UINT8_TO_BE_STREAM(start, key_code);
3951 BTA_AvRemoteVendorUniqueCmd(btif_rc_cb.rc_handle,
3953 (tBTA_AV_STATE)key_state, buffer,
3954 AVRC_PASS_THRU_GROUP_LEN);
3955 status = BT_STATUS_SUCCESS;
3956 BTIF_TRACE_DEBUG("%s: succesfully sent group_navigation command to BTA",
3961 status = BT_STATUS_FAIL;
3962 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
3967 status = BT_STATUS_FAIL;
3968 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
3971 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
3976 /***************************************************************************
3978 ** Function send_passthrough_cmd
3980 ** Description Send Pass-Through command
3984 ***************************************************************************/
3985 static bt_status_t send_passthrough_cmd(bt_bdaddr_t *bd_addr, uint8_t key_code, uint8_t key_state)
3987 tAVRC_STS status = BT_STATUS_UNSUPPORTED;
3988 #if (AVRC_CTLR_INCLUDED == TRUE)
3990 rc_transaction_t *p_transaction=NULL;
3991 BTIF_TRACE_DEBUG("%s: key-code: %d, key-state: %d", __FUNCTION__,
3992 key_code, key_state);
3993 if (btif_rc_cb.rc_features & BTA_AV_FEAT_RCTG)
3995 bt_status_t tran_status = get_transaction(&p_transaction);
3996 if (BT_STATUS_SUCCESS == tran_status && NULL != p_transaction)
3998 BTA_AvRemoteCmd(btif_rc_cb.rc_handle, p_transaction->lbl,
3999 (tBTA_AV_RC)key_code, (tBTA_AV_STATE)key_state);
4000 status = BT_STATUS_SUCCESS;
4001 BTIF_TRACE_DEBUG("%s: succesfully sent passthrough command to BTA", __FUNCTION__);
4005 status = BT_STATUS_FAIL;
4006 BTIF_TRACE_DEBUG("%s: error in fetching transaction", __FUNCTION__);
4011 status = BT_STATUS_FAIL;
4012 BTIF_TRACE_DEBUG("%s: feature not supported", __FUNCTION__);
4015 BTIF_TRACE_DEBUG("%s: feature not enabled", __FUNCTION__);
4020 static const btrc_interface_t bt_rc_interface = {
4021 sizeof(bt_rc_interface),
4023 get_play_status_rsp,
4024 NULL, /* list_player_app_attr_rsp */
4025 NULL, /* list_player_app_value_rsp */
4026 NULL, /* get_player_app_value_rsp */
4027 NULL, /* get_player_app_attr_text_rsp */
4028 NULL, /* get_player_app_value_text_rsp */
4029 get_element_attr_rsp,
4030 NULL, /* set_player_app_value_rsp */
4031 register_notification_rsp,
4036 static const btrc_ctrl_interface_t bt_rc_ctrl_interface = {
4037 sizeof(bt_rc_ctrl_interface),
4039 send_passthrough_cmd,
4040 send_groupnavigation_cmd,
4041 change_player_app_setting,
4043 volume_change_notification_rsp,
4047 /*******************************************************************************
4049 ** Function btif_rc_get_interface
4051 ** Description Get the AVRCP Target callback interface
4053 ** Returns btav_interface_t
4055 *******************************************************************************/
4056 const btrc_interface_t *btif_rc_get_interface(void)
4058 BTIF_TRACE_EVENT("%s", __FUNCTION__);
4059 return &bt_rc_interface;
4062 /*******************************************************************************
4064 ** Function btif_rc_ctrl_get_interface
4066 ** Description Get the AVRCP Controller callback interface
4068 ** Returns btav_interface_t
4070 *******************************************************************************/
4071 const btrc_ctrl_interface_t *btif_rc_ctrl_get_interface(void)
4073 BTIF_TRACE_EVENT("%s", __FUNCTION__);
4074 return &bt_rc_ctrl_interface;
4077 /*******************************************************************************
4078 ** Function initialize_transaction
4080 ** Description Initializes fields of the transaction structure
4083 *******************************************************************************/
4084 static void initialize_transaction(int lbl)
4086 pthread_mutex_lock(&device.lbllock);
4087 if (lbl < MAX_TRANSACTIONS_PER_SESSION) {
4088 if (alarm_is_scheduled(device.transaction[lbl].txn_timer)) {
4089 clear_cmd_timeout(lbl);
4091 device.transaction[lbl].lbl = lbl;
4092 device.transaction[lbl].in_use=FALSE;
4093 device.transaction[lbl].handle=0;
4095 pthread_mutex_unlock(&device.lbllock);
4098 /*******************************************************************************
4099 ** Function lbl_init
4101 ** Description Initializes label structures and mutexes.
4104 *******************************************************************************/
4107 memset(&device,0,sizeof(rc_device_t));
4108 pthread_mutexattr_t attr;
4109 pthread_mutexattr_init(&attr);
4110 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
4111 pthread_mutex_init(&(device.lbllock), &attr);
4112 pthread_mutexattr_destroy(&attr);
4113 init_all_transactions();
4116 /*******************************************************************************
4118 ** Function init_all_transactions
4120 ** Description Initializes all transactions
4123 *******************************************************************************/
4124 void init_all_transactions()
4127 for(txn_indx=0; txn_indx < MAX_TRANSACTIONS_PER_SESSION; txn_indx++)
4129 initialize_transaction(txn_indx);
4133 /*******************************************************************************
4135 ** Function get_transaction_by_lbl
4137 ** Description Will return a transaction based on the label. If not inuse
4138 ** will return an error.
4140 ** Returns bt_status_t
4141 *******************************************************************************/
4142 rc_transaction_t *get_transaction_by_lbl(UINT8 lbl)
4144 rc_transaction_t *transaction = NULL;
4145 pthread_mutex_lock(&device.lbllock);
4147 /* Determine if this is a valid label */
4148 if (lbl < MAX_TRANSACTIONS_PER_SESSION)
4150 if (FALSE==device.transaction[lbl].in_use)
4156 transaction = &(device.transaction[lbl]);
4157 BTIF_TRACE_DEBUG("%s: Got transaction.label: %d",__FUNCTION__,lbl);
4161 pthread_mutex_unlock(&device.lbllock);
4165 /*******************************************************************************
4167 ** Function get_transaction
4169 ** Description Obtains the transaction details.
4171 ** Returns bt_status_t
4172 *******************************************************************************/
4174 bt_status_t get_transaction(rc_transaction_t **ptransaction)
4176 bt_status_t result = BT_STATUS_NOMEM;
4178 pthread_mutex_lock(&device.lbllock);
4180 // Check for unused transactions
4181 for (i=0; i<MAX_TRANSACTIONS_PER_SESSION; i++)
4183 if (FALSE==device.transaction[i].in_use)
4185 BTIF_TRACE_DEBUG("%s:Got transaction.label: %d",__FUNCTION__,device.transaction[i].lbl);
4186 device.transaction[i].in_use = TRUE;
4187 *ptransaction = &(device.transaction[i]);
4188 result = BT_STATUS_SUCCESS;
4193 pthread_mutex_unlock(&device.lbllock);
4197 /*******************************************************************************
4199 ** Function release_transaction
4201 ** Description Will release a transaction for reuse
4203 ** Returns bt_status_t
4204 *******************************************************************************/
4205 void release_transaction(UINT8 lbl)
4207 rc_transaction_t *transaction = get_transaction_by_lbl(lbl);
4209 /* If the transaction is in use... */
4210 if (transaction != NULL)
4212 BTIF_TRACE_DEBUG("%s: lbl: %d", __FUNCTION__, lbl);
4213 initialize_transaction(lbl);
4217 /*******************************************************************************
4219 ** Function lbl_destroy
4221 ** Description Cleanup of the mutex
4224 *******************************************************************************/
4227 pthread_mutex_destroy(&(device.lbllock));
4230 /*******************************************************************************
4231 ** Function sleep_ms
4233 ** Description Sleep the calling thread unconditionally for
4234 ** |timeout_ms| milliseconds.
4237 *******************************************************************************/
4238 static void sleep_ms(period_ms_t timeout_ms) {
4239 struct timespec delay;
4240 delay.tv_sec = timeout_ms / 1000;
4241 delay.tv_nsec = 1000 * 1000 * (timeout_ms % 1000);
4245 err = nanosleep(&delay, &delay);
4246 } while (err == -1 && errno == EINTR);
4249 static bool absolute_volume_disabled() {
4250 #if !defined(OS_GENERIC)
4251 char volume_disabled[PROPERTY_VALUE_MAX] = {0};
4252 property_get("persist.bluetooth.disableabsvol", volume_disabled, "false");
4253 if (strncmp(volume_disabled, "true", 4) == 0) {
4254 BTIF_TRACE_WARNING("%s: Absolute volume disabled by property", __func__);
4257 #endif /* !defined(OS_GENERIC) */