2 * Open Adaptation Layer (OAL)
4 * Copyright (c) 2014-2015 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include "bluetooth.h"
27 #include "oal-event.h"
28 #include "oal-internal.h"
29 #include "oal-common.h"
30 #include "oal-manager.h"
31 #include "oal-avrcp-tg.h"
33 #define NUM_MEDIA_ATTR_MAX (BTRC_MEDIA_ATTR_PLAYING_TIME)
35 #define CHECK_OAL_AVRCP_ENABLED() \
37 if (avrcp_api == NULL) { \
38 BT_ERR("AVRCP Not Enabled"); \
39 return OAL_STATUS_NOT_READY; \
43 static void remove_pos_timer();
46 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state);
49 static void cb_avrcp_remote_features(bt_bdaddr_t* bd_addr, btrc_remote_features_t features);
51 static void cb_avrcp_get_play_status();
52 static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bdaddr_t *bd_addr);
53 static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr);
54 static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr);
55 static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr);
56 static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr);
57 static void cb_avrcp_passthrough_command(int id, int pressed, bt_bdaddr_t *bd_addr);
71 btrc_player_repeat_val_t repeat;
72 btrc_player_shuffle_val_t shuffle;
74 btrc_play_status_t status;
80 uint32_t playing_time;
81 uint8_t title[BTRC_MAX_ATTR_STR_LEN];
82 uint8_t artist[BTRC_MAX_ATTR_STR_LEN];
83 uint8_t album[BTRC_MAX_ATTR_STR_LEN];
84 uint8_t genre[BTRC_MAX_ATTR_STR_LEN];
85 unsigned int num_tracks;
90 STATUS_STOPPED = 0x00,
97 } media_player_status;
99 static track_info_t track_info;
100 static player_settings_t player_setting;
102 static guint send_pos_timer = 0;
104 static notif_t registered_notifications;
105 static const btrc_interface_t *avrcp_api;
107 static btrc_callbacks_t sBluetoothAvrcpCallbacks = {
108 .size = sizeof(sBluetoothAvrcpCallbacks),
110 .connection_state_cb = cb_connection_state,
112 .remote_features_cb = cb_avrcp_remote_features,
113 .get_play_status_cb = cb_avrcp_get_play_status,
114 .list_player_app_attr_cb = NULL,
115 .list_player_app_values_cb = NULL,
116 .get_player_app_value_cb = NULL,
117 .get_player_app_attrs_text_cb = NULL,
118 .get_player_app_values_text_cb = NULL,
119 .set_player_app_value_cb = cb_avrcp_set_player_app_value,
120 .get_element_attr_cb = cb_avrcp_get_element_attr,
121 .register_notification_cb = cb_avrcp_register_notification,
122 .volume_change_cb = cb_avrcp_volume_change,
123 .delay_change_cb = cb_avrcp_delay_change,
124 .passthrough_cmd_cb = cb_avrcp_passthrough_command,
125 .set_addressed_player_cb = NULL,
126 .set_browsed_player_cb = NULL,
127 .get_folder_items_cb = NULL,
128 .change_path_cb = NULL,
129 .get_item_attr_cb = NULL,
130 .play_item_cb = NULL,
131 .get_total_num_of_items_cb = NULL,
133 .add_to_now_playing_cb = NULL,
136 static void send_pos_changed(void)
138 BT_DBG("Pos changed");
140 if (avrcp_api == NULL) {
141 BT_ERR("AVRCP Not Enabled");
145 if (registered_notifications.pos_change) {
147 btrc_register_notification_t response;
149 BT_DBG("Song Pos: %d", track_info.song_pos);
150 response.song_pos = track_info.song_pos;
151 ret = avrcp_api->register_notification_rsp(
152 BTRC_EVT_PLAY_POS_CHANGED, BTRC_NOTIFICATION_TYPE_CHANGED, &response);
154 if (ret != BT_STATUS_SUCCESS)
155 BT_ERR("Notif send failed: %s", status2string(ret));
159 static gboolean send_pos_timeout(gpointer param)
161 BT_DBG("pos timeout");
163 if (!registered_notifications.pos_change)
168 if (player_setting.status != BTRC_PLAYSTATE_PLAYING &&
169 player_setting.status != BTRC_PLAYSTATE_FWD_SEEK &&
170 player_setting.status != BTRC_PLAYSTATE_REV_SEEK)
176 static void remove_pos_timer()
179 if (send_pos_timer > 0) {
180 g_source_remove(send_pos_timer);
185 static void send_track_boundary_reached(void)
187 int ret = BT_STATUS_SUCCESS;
189 if (avrcp_api == NULL) {
190 BT_ERR("AVRCP Not Enabled");
194 if (track_info.song_pos == 0 &&
195 registered_notifications.track_start)
196 ret = avrcp_api->register_notification_rsp(
197 BTRC_EVT_TRACK_REACHED_START, BTRC_NOTIFICATION_TYPE_CHANGED, NULL);
198 else if ((track_info.playing_time == track_info.song_pos) &&
199 registered_notifications.track_end) {
200 ret = avrcp_api->register_notification_rsp(
201 BTRC_EVT_TRACK_REACHED_END, BTRC_NOTIFICATION_TYPE_CHANGED, NULL);
204 if (ret != BT_STATUS_SUCCESS)
205 BT_ERR("Notif send failed: %s", status2string(ret));
208 gboolean avrcp_tg_enable_state(void)
210 if (avrcp_api == NULL)
216 oal_status_t avrcp_enable(void)
218 const bt_interface_t * blued_api = NULL;
223 /*TODO: Need to check below logic */
225 if (a2dp_sink_enable_state() == TRUE || avrcp_ct_enable_state() == TRUE) {
226 BT_ERR("AVRCP_CT Role Enabled, cannot enable AVRCP_TG Role");
227 return OAL_STATUS_BUSY;
231 blued_api = adapter_get_stack_interface();
232 if (blued_api == NULL) {
233 BT_ERR("Stack is not initialized");
234 return OAL_STATUS_NOT_READY;
238 BT_WARN("avrcp tg Interface is already initialized...");
239 return OAL_STATUS_ALREADY_DONE;
242 avrcp_api = (const btrc_interface_t *)blued_api->get_profile_interface(BT_PROFILE_AV_RC_ID);
243 if (avrcp_api == NULL) {
244 BT_ERR("AVRCP interface failed");
245 return OAL_STATUS_INTERNAL_ERROR;
248 memset(®istered_notifications, 0x00, sizeof(registered_notifications));
249 memset(&track_info, 0x00, sizeof(track_info));
250 memset(&player_setting, 0, sizeof(player_settings_t));
252 /* Handle failure if return value is anything other than Success or Already done */
253 ret = avrcp_api->init(&sBluetoothAvrcpCallbacks);
254 if (ret != BT_STATUS_SUCCESS && ret != BT_STATUS_DONE) {
255 BT_ERR("AVRCP Init failed %s", status2string(ret));
256 avrcp_api->cleanup();
258 return convert_to_oal_status(ret);
261 return OAL_STATUS_SUCCESS;
264 oal_status_t avrcp_disable(void)
269 CHECK_OAL_AVRCP_ENABLED();
272 avrcp_api->cleanup();
275 return OAL_STATUS_SUCCESS;
278 void avrcp_tg_cleanup(void)
287 oal_status_t avrcp_tg_connect(bt_address_t *rem_addr)
289 int result = OAL_STATUS_SUCCESS;
295 CHECK_OAL_AVRCP_ENABLED();
296 OAL_CHECK_PARAMETER(rem_addr, return);
298 BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
301 status = avrcp_api->connect((bt_bdaddr_t *)rem_addr);
302 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
303 BT_ERR("Connection could not be established, err: %s", status2string(status));;
304 result = convert_to_oal_status(status);
307 BT_INFO("Not Supported");
308 result = OAL_STATUS_NOT_SUPPORT;
314 oal_status_t avrcp_tg_disconnect(bt_address_t *rem_addr)
316 int result = OAL_STATUS_SUCCESS;
322 CHECK_OAL_AVRCP_ENABLED();
323 OAL_CHECK_PARAMETER(rem_addr, return);
325 BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
328 status = avrcp_api->disconnect((bt_bdaddr_t *)rem_addr);
329 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
330 BT_ERR("OAL, Disconnection failed err: %s", status2string(status));
331 result = convert_to_oal_status(status);
334 BT_INFO("Not Supported");
335 result = OAL_STATUS_NOT_SUPPORT;
341 oal_status_t avrcp_set_track_info(oal_media_metadata_attributes_t *meta_data)
345 CHECK_OAL_AVRCP_ENABLED();
347 retv_if(meta_data == NULL, OAL_STATUS_INTERNAL_ERROR);
349 /********* Update media attribs **********/
350 g_strlcpy((char*)track_info.title, meta_data->title, BTRC_MAX_ATTR_STR_LEN);
351 g_strlcpy((char*)track_info.artist, meta_data->artist, BTRC_MAX_ATTR_STR_LEN);
352 g_strlcpy((char*)track_info.album, meta_data->album, BTRC_MAX_ATTR_STR_LEN);
353 g_strlcpy((char*)track_info.genre, meta_data->genre, BTRC_MAX_ATTR_STR_LEN);
355 track_info.num_tracks = meta_data->total_tracks;
356 track_info.playing_time = meta_data->duration;
358 if (registered_notifications.track_change &&
359 track_info.cur_track != meta_data->number) {
361 btrc_register_notification_t response;
363 memset(&response, 0x00, sizeof(btrc_register_notification_t));
365 track_info.cur_track = meta_data->number;
367 /* Send Track Change notification */
368 memcpy(&response.track, &track_info.cur_track, sizeof(uint32_t));
369 ret = avrcp_api->register_notification_rsp(
370 BTRC_EVT_TRACK_CHANGE, BTRC_NOTIFICATION_TYPE_CHANGED, &response);
371 if (ret != BT_STATUS_SUCCESS)
372 BT_ERR("Notif send failed: %s", status2string(ret));
377 track_info.cur_track = meta_data->number;
378 return OAL_STATUS_SUCCESS;
381 oal_status_t avrcp_set_property(int type, unsigned int value)
383 btrc_register_notification_t response;
386 API_TRACE("type: %d, value: %d", type, value);
387 CHECK_OAL_AVRCP_ENABLED();
390 case AVRCP_EQUALIZER: {
391 if (value == player_setting.equalizer &&
392 !registered_notifications.setting_change)
395 response.player_setting.num_attr = 1;
396 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_EQUALIZER;
397 response.player_setting.attr_values[0] = value;
398 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
399 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
400 if (ret != BT_STATUS_SUCCESS)
401 BT_ERR("Notif send failed: %s", status2string(ret));
403 player_setting.equalizer = value;
407 if (value == player_setting.repeat &&
408 !registered_notifications.setting_change)
411 response.player_setting.num_attr = 1;
412 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_REPEAT;
413 response.player_setting.attr_values[0] = value;
414 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
415 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
416 if (ret != BT_STATUS_SUCCESS)
417 BT_ERR("Notif send failed: %s", status2string(ret));
419 player_setting.repeat = value;
422 case AVRCP_SHUFFLE: {
423 if (value == player_setting.shuffle &&
424 !registered_notifications.setting_change)
427 response.player_setting.num_attr = 1;
428 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SHUFFLE;
429 response.player_setting.attr_values[0] = value;
430 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
431 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
432 if (ret != BT_STATUS_SUCCESS)
433 BT_ERR("Notif send failed: %s", status2string(ret));
435 player_setting.shuffle = value;
439 if (value == player_setting.scan &&
440 !registered_notifications.setting_change)
443 response.player_setting.num_attr = 1;
444 response.player_setting.attr_ids[0] = BTRC_PLAYER_ATTR_SCAN;
445 response.player_setting.attr_values[0] = value;
446 ret = avrcp_api->register_notification_rsp(BTRC_EVT_APP_SETTINGS_CHANGED,
447 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
448 if (ret != BT_STATUS_SUCCESS)
449 BT_ERR("Notif send failed: %s", status2string(ret));
451 player_setting.scan = value;
455 if (value != player_setting.status) {
456 btrc_play_status_t play_status = player_setting.status;
458 player_setting.status = (value == STATUS_ERROR) ? BTRC_PLAYSTATE_ERROR : value;
460 if (registered_notifications.play_status) {
461 gboolean is_timer = FALSE;
463 response.play_status = player_setting.status;
464 ret = avrcp_api->register_notification_rsp(BTRC_EVT_PLAY_STATUS_CHANGED,
465 BTRC_NOTIFICATION_TYPE_CHANGED, &response);
466 if (ret != BT_STATUS_SUCCESS)
467 BT_ERR("Notif send failed: %s", status2string(ret));
469 /* Check if old and new status value are changed from NOT PLAYING to PLAYING */
470 switch (play_status) {
471 case BTRC_PLAYSTATE_ERROR: /* Intentional fall-through */
472 case BTRC_PLAYSTATE_STOPPED: /* Intentional fall-through */
473 case BTRC_PLAYSTATE_PAUSED: /* Intentional fall-through */
474 if (STATUS_PLAYING == value ||
475 STATUS_REVERSE_SEEK == value ||
476 STATUS_FORWARD_SEEK == value) {
477 BT_INFO("Play status changed from stopped to playing");
486 BT_DBG("Player is playing mode, start sending pos change notifications");
488 send_pos_timer = g_timeout_add(registered_notifications.interval * 1000,
489 send_pos_timeout, NULL);
495 if (value != track_info.song_pos) {
496 track_info.song_pos = value;
498 send_track_boundary_reached();
502 BT_ERR("Invalid Type\n");
503 return OAL_STATUS_INTERNAL_ERROR;
506 return OAL_STATUS_SUCCESS;
510 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state)
512 bt_address_t * event_data = NULL;
517 event_data = g_new0(bt_address_t, 1);
518 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
521 case BTRC_CONNECTION_STATE_DISCONNECTED:
522 event = OAL_EVENT_AVRCP_DISCONNECTED;
524 case BTRC_CONNECTION_STATE_CONNECTED:
525 event = OAL_EVENT_AVRCP_CONNECTED;
528 BT_ERR("Unhandled Connection state %d", state);
532 send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
537 static void cb_avrcp_remote_features(bt_bdaddr_t* bd_addr, btrc_remote_features_t features)
539 remote_feature *avrcp_rem_feature = g_new0(remote_feature, 1);
541 /* Reset variables */
542 memset(®istered_notifications, 0, sizeof(notif_t));
543 memset(&track_info, 0, sizeof(track_info_t));
544 memset(&player_setting, 0, sizeof(player_settings_t));
545 player_setting.volume = 0xFFFFFFFF/2;
547 /* TODO: need to check if this feature mask is useful */
548 BT_INFO("Remore features Mask: 0x%x", features);
550 avrcp_rem_feature->avrcp_feature = features;
551 memcpy(avrcp_rem_feature->address.addr, bd_addr->address, 6);
553 send_event_bda_trace(OAL_EVENT_AVRCP_REMOTE_FEATURES,
554 avrcp_rem_feature, sizeof(remote_feature), (bt_address_t *)bd_addr);
557 static void cb_avrcp_get_play_status(bt_bdaddr_t *bd_addr)
563 if (avrcp_api == NULL) {
564 BT_ERR("AVRCP Not Enabled");
568 ret = avrcp_api->get_play_status_rsp(bd_addr, player_setting.status,
569 track_info.playing_time, track_info.song_pos);
570 if (ret != BT_STATUS_SUCCESS)
571 BT_ERR("Play Status send failed: %s", status2string(ret));
574 static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bdaddr_t *bd_addr)
582 for (i = 0; i < p_vals->num_attr; i++) {
585 switch (p_vals->attr_ids[i]) {
586 case BTRC_PLAYER_ATTR_EQUALIZER:
587 event = OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS;
589 case BTRC_PLAYER_ATTR_REPEAT:
590 event = OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS;
592 case BTRC_PLAYER_ATTR_SHUFFLE:
593 event = OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS;
595 case BTRC_PLAYER_ATTR_SCAN:
596 event = OAL_EVENT_AVRCP_SETTING_SCAN_STATUS;
599 BT_ERR("Inavlid attr id= %d", p_vals->attr_ids[i]);
602 if (event != 0xffff) {
603 value = g_new0(uint8_t, 1);
604 *value = p_vals->attr_values[i];
605 send_event(event, value, sizeof(*value));
610 static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr)
612 btrc_element_attr_val_t *p_attrs_vals;
616 if (avrcp_api == NULL) {
617 BT_ERR("AVRCP Not Enabled");
621 if (p_attrs == NULL) {
622 BT_ERR("p_attrs is NULL");
626 BT_DBG("num_attr: %d", num_attr);
627 p_attrs_vals = g_malloc0(num_attr * sizeof(btrc_element_attr_val_t));
629 for (i = 0; i < num_attr; i++) {
630 p_attrs_vals[i].attr_id = p_attrs[i];
632 switch (p_attrs[i]) {
633 case BTRC_MEDIA_ATTR_TITLE:
634 g_strlcpy((char*)p_attrs_vals[i].text,
635 (const char *)track_info.title, BTRC_MAX_ATTR_STR_LEN);
637 case BTRC_MEDIA_ATTR_ARTIST:
638 g_strlcpy((char*)p_attrs_vals[i].text,
639 (const char *)track_info.artist, BTRC_MAX_ATTR_STR_LEN);
641 case BTRC_MEDIA_ATTR_ALBUM:
642 g_strlcpy((char*)p_attrs_vals[i].text,
643 (const char *)track_info.album, BTRC_MAX_ATTR_STR_LEN);
645 case BTRC_MEDIA_ATTR_TRACK_NUM:
646 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.cur_track);
648 case BTRC_MEDIA_ATTR_NUM_TRACKS:
649 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.num_tracks);
651 case BTRC_MEDIA_ATTR_GENRE:
652 g_strlcpy((char*)p_attrs_vals[i].text,
653 (const char *)track_info.genre, BTRC_MAX_ATTR_STR_LEN);
655 case BTRC_MEDIA_ATTR_PLAYING_TIME:
656 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.playing_time);
659 BT_ERR("Inavlid attr id= %d", p_attrs[i]);
663 ret = avrcp_api->get_element_attr_rsp(bd_addr, num_attr, p_attrs_vals);
664 if (ret != BT_STATUS_SUCCESS)
665 BT_ERR("Element attr send failed: %s", status2string(ret));
667 g_free(p_attrs_vals);
670 static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr)
672 btrc_register_notification_t response;
675 BT_DBG("event_id: 0x%x", event_id);
677 if (avrcp_api == NULL) {
678 BT_ERR("AVRCP Not Enabled");
681 memset(&response, 0x00, sizeof(btrc_register_notification_t));
684 case BTRC_EVT_PLAY_STATUS_CHANGED:
685 registered_notifications.play_status = 1;
686 response.play_status = player_setting.status;
687 ret = avrcp_api->register_notification_rsp(
688 BTRC_EVT_PLAY_STATUS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
690 case BTRC_EVT_TRACK_CHANGE:
691 registered_notifications.track_change = 1;
692 memcpy(response.track, &track_info.cur_track, sizeof(uint32_t));
693 ret = avrcp_api->register_notification_rsp(
694 BTRC_EVT_TRACK_CHANGE, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
696 case BTRC_EVT_TRACK_REACHED_END:
697 registered_notifications.track_end = 1;
698 ret = avrcp_api->register_notification_rsp(
699 BTRC_EVT_TRACK_REACHED_END, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
701 case BTRC_EVT_TRACK_REACHED_START:
702 registered_notifications.track_start = 1;
703 ret = avrcp_api->register_notification_rsp(
704 BTRC_EVT_TRACK_REACHED_START, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
706 case BTRC_EVT_PLAY_POS_CHANGED:
707 registered_notifications.pos_change = 1;
708 registered_notifications.interval = param;
709 BT_DBG("Pos will be notified every %d secs", param);
711 * start a timer with value of interval and send rsp on each timer fire.
712 * Other then this in below situations also send the response:
713 * - Change in Play status
714 * - Change in current track
715 * - Reach end or beginning of track
717 response.song_pos = track_info.song_pos;
718 ret = avrcp_api->register_notification_rsp(
719 BTRC_EVT_PLAY_POS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
721 send_pos_timer = g_timeout_add(param * 1000, send_pos_timeout, NULL);
723 case BTRC_EVT_APP_SETTINGS_CHANGED:
724 registered_notifications.setting_change = 1;
725 ret = avrcp_api->register_notification_rsp(
726 BTRC_EVT_APP_SETTINGS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
729 BT_ERR("Invalid event id: 0x%x", event_id);
730 ret = BT_STATUS_FAIL;
733 if (ret != BT_STATUS_SUCCESS)
734 BT_ERR("Notif send failed: %s", status2string(ret));
737 static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr)
740 oal_avrcp_volume_mute_t *avrcp_volume_mute = g_new0(oal_avrcp_volume_mute_t, 1);
742 BT_INFO("volume: %d, ctype: %d", volume, ctype);
743 player_setting.volume = volume;
745 avrcp_volume_mute->volume = volume;
747 avrcp_volume_mute->mute_status = TRUE;
749 avrcp_volume_mute->mute_status = FALSE;
751 send_event(OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED,
752 avrcp_volume_mute, sizeof(oal_avrcp_volume_mute_t));
755 static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr)
757 BT_INFO("Delay : %d", delay);
758 oal_avrcp_delay_t *avrcp_delay = g_new0(oal_avrcp_delay_t, 1);
759 avrcp_delay->delay = delay;
761 send_event(OAL_EVENT_AVRCP_DELAY_CHANGED,
762 avrcp_delay, sizeof(oal_avrcp_delay_t));
765 static void cb_avrcp_passthrough_command(int id, int key_state, bt_bdaddr_t *bd_addr)
767 BT_DBG("id: %d, key_state: %d", id, key_state);
768 //TODO: need to check