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;
509 oal_status_t avrcp_tg_set_volume(bt_address_t *rem_addr, unsigned int volume)
511 int result = OAL_STATUS_SUCCESS;
517 CHECK_OAL_AVRCP_ENABLED();
518 OAL_CHECK_PARAMETER(rem_addr, return);
520 BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
523 status = avrcp_api->set_volume((bt_bdaddr_t *)rem_addr, volume);
524 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
525 BT_ERR("set volume failed, err: %s", status2string(status));;
526 result = convert_to_oal_status(status);
529 BT_INFO("Not Supported");
530 result = OAL_STATUS_NOT_SUPPORT;
536 oal_status_t avrcp_tg_get_volume(bt_address_t *rem_addr, unsigned int *volume)
538 int result = OAL_STATUS_SUCCESS;
544 CHECK_OAL_AVRCP_ENABLED();
545 OAL_CHECK_PARAMETER(rem_addr, return);
547 BT_INFO("BT Audio Address: %s", bdt_bd2str(rem_addr, &bdstr));
550 status = avrcp_api->get_volume((bt_bdaddr_t *)rem_addr, volume);
551 if ((status != BT_STATUS_SUCCESS) && (status != BT_STATUS_DONE)) {
552 BT_ERR("set volume failed, err: %s", status2string(status));;
553 result = convert_to_oal_status(status);
556 BT_INFO("Not Supported");
557 result = OAL_STATUS_NOT_SUPPORT;
565 static void cb_connection_state(bt_bdaddr_t* bd_addr, btrc_connection_state_t state)
567 bt_address_t * event_data = NULL;
572 event_data = g_new0(bt_address_t, 1);
573 memcpy(event_data->addr, bd_addr->address, BT_ADDRESS_BYTES_NUM);
576 case BTRC_CONNECTION_STATE_DISCONNECTED:
577 event = OAL_EVENT_AVRCP_DISCONNECTED;
579 case BTRC_CONNECTION_STATE_CONNECTED:
580 event = OAL_EVENT_AVRCP_CONNECTED;
583 BT_ERR("Unhandled Connection state %d", state);
587 send_event_bda_trace(event, event_data, sizeof(bt_address_t), (bt_address_t*)bd_addr);
592 static void cb_avrcp_remote_features(bt_bdaddr_t* bd_addr, btrc_remote_features_t features)
594 remote_feature *avrcp_rem_feature = g_new0(remote_feature, 1);
596 /* Reset variables */
597 memset(®istered_notifications, 0, sizeof(notif_t));
598 memset(&track_info, 0, sizeof(track_info_t));
599 memset(&player_setting, 0, sizeof(player_settings_t));
600 player_setting.volume = 0xFFFFFFFF/2;
602 /* TODO: need to check if this feature mask is useful */
603 BT_INFO("Remore features Mask: 0x%x", features);
605 avrcp_rem_feature->avrcp_feature = features;
606 memcpy(avrcp_rem_feature->address.addr, bd_addr->address, 6);
608 send_event_bda_trace(OAL_EVENT_AVRCP_REMOTE_FEATURES,
609 avrcp_rem_feature, sizeof(remote_feature), (bt_address_t *)bd_addr);
612 static void cb_avrcp_get_play_status(bt_bdaddr_t *bd_addr)
618 if (avrcp_api == NULL) {
619 BT_ERR("AVRCP Not Enabled");
623 ret = avrcp_api->get_play_status_rsp(bd_addr, player_setting.status,
624 track_info.playing_time, track_info.song_pos);
625 if (ret != BT_STATUS_SUCCESS)
626 BT_ERR("Play Status send failed: %s", status2string(ret));
629 static void cb_avrcp_set_player_app_value(btrc_player_settings_t *p_vals, bt_bdaddr_t *bd_addr)
637 for (i = 0; i < p_vals->num_attr; i++) {
640 switch (p_vals->attr_ids[i]) {
641 case BTRC_PLAYER_ATTR_EQUALIZER:
642 event = OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS;
644 case BTRC_PLAYER_ATTR_REPEAT:
645 event = OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS;
647 case BTRC_PLAYER_ATTR_SHUFFLE:
648 event = OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS;
650 case BTRC_PLAYER_ATTR_SCAN:
651 event = OAL_EVENT_AVRCP_SETTING_SCAN_STATUS;
654 BT_ERR("Inavlid attr id= %d", p_vals->attr_ids[i]);
657 if (event != 0xffff) {
658 value = g_new0(uint8_t, 1);
659 *value = p_vals->attr_values[i];
660 send_event(event, value, sizeof(*value));
665 static void cb_avrcp_get_element_attr(uint8_t num_attr, btrc_media_attr_t *p_attrs, bt_bdaddr_t *bd_addr)
667 btrc_element_attr_val_t *p_attrs_vals;
671 if (avrcp_api == NULL) {
672 BT_ERR("AVRCP Not Enabled");
676 if (p_attrs == NULL) {
677 BT_ERR("p_attrs is NULL");
681 BT_DBG("num_attr: %d", num_attr);
682 p_attrs_vals = g_malloc0(num_attr * sizeof(btrc_element_attr_val_t));
684 for (i = 0; i < num_attr; i++) {
685 p_attrs_vals[i].attr_id = p_attrs[i];
687 switch (p_attrs[i]) {
688 case BTRC_MEDIA_ATTR_TITLE:
689 g_strlcpy((char*)p_attrs_vals[i].text,
690 (const char *)track_info.title, BTRC_MAX_ATTR_STR_LEN);
692 case BTRC_MEDIA_ATTR_ARTIST:
693 g_strlcpy((char*)p_attrs_vals[i].text,
694 (const char *)track_info.artist, BTRC_MAX_ATTR_STR_LEN);
696 case BTRC_MEDIA_ATTR_ALBUM:
697 g_strlcpy((char*)p_attrs_vals[i].text,
698 (const char *)track_info.album, BTRC_MAX_ATTR_STR_LEN);
700 case BTRC_MEDIA_ATTR_TRACK_NUM:
701 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.cur_track);
703 case BTRC_MEDIA_ATTR_NUM_TRACKS:
704 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.num_tracks);
706 case BTRC_MEDIA_ATTR_GENRE:
707 g_strlcpy((char*)p_attrs_vals[i].text,
708 (const char *)track_info.genre, BTRC_MAX_ATTR_STR_LEN);
710 case BTRC_MEDIA_ATTR_PLAYING_TIME:
711 snprintf((char*)p_attrs_vals[i].text, BTRC_MAX_ATTR_STR_LEN, "%u", track_info.playing_time);
714 BT_ERR("Inavlid attr id= %d", p_attrs[i]);
718 ret = avrcp_api->get_element_attr_rsp(bd_addr, num_attr, p_attrs_vals);
719 if (ret != BT_STATUS_SUCCESS)
720 BT_ERR("Element attr send failed: %s", status2string(ret));
722 g_free(p_attrs_vals);
725 static void cb_avrcp_register_notification(btrc_event_id_t event_id, uint32_t param, bt_bdaddr_t *bd_addr)
727 btrc_register_notification_t response;
730 BT_DBG("event_id: 0x%x", event_id);
732 if (avrcp_api == NULL) {
733 BT_ERR("AVRCP Not Enabled");
736 memset(&response, 0x00, sizeof(btrc_register_notification_t));
739 case BTRC_EVT_PLAY_STATUS_CHANGED:
740 registered_notifications.play_status = 1;
741 response.play_status = player_setting.status;
742 ret = avrcp_api->register_notification_rsp(
743 BTRC_EVT_PLAY_STATUS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
745 case BTRC_EVT_TRACK_CHANGE:
746 registered_notifications.track_change = 1;
747 memcpy(response.track, &track_info.cur_track, sizeof(uint32_t));
748 ret = avrcp_api->register_notification_rsp(
749 BTRC_EVT_TRACK_CHANGE, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
751 case BTRC_EVT_TRACK_REACHED_END:
752 registered_notifications.track_end = 1;
753 ret = avrcp_api->register_notification_rsp(
754 BTRC_EVT_TRACK_REACHED_END, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
756 case BTRC_EVT_TRACK_REACHED_START:
757 registered_notifications.track_start = 1;
758 ret = avrcp_api->register_notification_rsp(
759 BTRC_EVT_TRACK_REACHED_START, BTRC_NOTIFICATION_TYPE_INTERIM, NULL);
761 case BTRC_EVT_PLAY_POS_CHANGED:
762 registered_notifications.pos_change = 1;
763 registered_notifications.interval = param;
764 BT_DBG("Pos will be notified every %d secs", param);
766 * start a timer with value of interval and send rsp on each timer fire.
767 * Other then this in below situations also send the response:
768 * - Change in Play status
769 * - Change in current track
770 * - Reach end or beginning of track
772 response.song_pos = track_info.song_pos;
773 ret = avrcp_api->register_notification_rsp(
774 BTRC_EVT_PLAY_POS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
776 send_pos_timer = g_timeout_add(param * 1000, send_pos_timeout, NULL);
778 case BTRC_EVT_APP_SETTINGS_CHANGED:
779 registered_notifications.setting_change = 1;
780 ret = avrcp_api->register_notification_rsp(
781 BTRC_EVT_APP_SETTINGS_CHANGED, BTRC_NOTIFICATION_TYPE_INTERIM, &response);
784 BT_ERR("Invalid event id: 0x%x", event_id);
785 ret = BT_STATUS_FAIL;
788 if (ret != BT_STATUS_SUCCESS)
789 BT_ERR("Notif send failed: %s", status2string(ret));
792 static void cb_avrcp_volume_change(uint8_t volume, uint8_t ctype, bt_bdaddr_t *bd_addr)
795 oal_avrcp_volume_mute_t *avrcp_volume_mute = g_new0(oal_avrcp_volume_mute_t, 1);
797 BT_INFO("volume: %d, ctype: %d", volume, ctype);
798 player_setting.volume = volume;
800 avrcp_volume_mute->volume = volume;
802 avrcp_volume_mute->mute_status = TRUE;
804 avrcp_volume_mute->mute_status = FALSE;
806 send_event(OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED,
807 avrcp_volume_mute, sizeof(oal_avrcp_volume_mute_t));
810 static void cb_avrcp_delay_change(uint16_t delay, bt_bdaddr_t *bd_addr)
812 BT_INFO("Delay : %d", delay);
813 oal_avrcp_delay_t *avrcp_delay = g_new0(oal_avrcp_delay_t, 1);
814 avrcp_delay->delay = delay;
816 send_event(OAL_EVENT_AVRCP_DELAY_CHANGED,
817 avrcp_delay, sizeof(oal_avrcp_delay_t));
820 static void cb_avrcp_passthrough_command(int id, int key_state, bt_bdaddr_t *bd_addr)
822 BT_DBG("id: %d, key_state: %d", id, key_state);
823 //TODO: need to check