2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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.
22 #include <dbus/dbus.h>
24 #include <oal-avrcp-tg.h>
26 #include "bluetooth-api.h"
27 #include "bt-internal-types.h"
28 #include "bt-service-common.h"
29 #include "bt-service-avrcp-tg.h"
30 #include "bt-service-event.h"
31 #include "bt-service-event-receiver.h"
32 #include "bt-service-audio-common.h"
33 #include "bt-service-util.h"
35 static invocation_info_t* __bt_get_request_info(int service_function, char *address)
38 invocation_info_t *req_info = NULL;
42 retv_if(NULL == address, FALSE);
44 /* Get method invocation context */
45 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
47 if (req_info == NULL || req_info->service_function != service_function)
50 if (!strncasecmp((char *)req_info->user_data, address, BT_ADDRESS_STRING_SIZE))
57 static int __bt_avrcp_set_equalizer(media_player_equalizer_status equalizer)
72 BT_ERR("Invalid Equalizer state");
73 return BLUETOOTH_ERROR_INTERNAL;
76 result = avrcp_set_property(AVRCP_EQUALIZER, value);
77 if (result != OAL_STATUS_SUCCESS) {
78 BT_ERR("avrcp_set_property failed");
79 return _bt_convert_oal_status_to_bt_error(result);
83 return BLUETOOTH_ERROR_NONE;
86 static int __bt_avrcp_set_repeat_status(media_player_repeat_status repeat_status)
93 switch (repeat_status) {
95 value = OAL_PLAYER_VAL_OFF_REPEAT;
97 case REPEAT_SINGLE_TRACK:
98 value = OAL_PLAYER_VAL_SINGLE_REPEAT;
100 case REPEAT_ALL_TRACK:
101 value = OAL_PLAYER_VAL_ALL_REPEAT;
104 value = OAL_PLAYER_VAL_GROUP_REPEAT;
107 BT_ERR("Invalid repeat status");
108 return BLUETOOTH_ERROR_INTERNAL;
111 result = avrcp_set_property(AVRCP_REPEAT, value);
112 if (result != OAL_STATUS_SUCCESS) {
113 BT_ERR("avrcp_set_property failed");
114 return _bt_convert_oal_status_to_bt_error(result);
118 return BLUETOOTH_ERROR_NONE;
121 static int __bt_avrcp_set_shuffel_mode(media_player_shuffle_status shuffel)
129 case SHUFFLE_MODE_OFF:
130 value = OAL_PLAYER_VAL_OFF_SHUFFLE;
132 case SHUFFLE_ALL_TRACK:
133 value = OAL_PLAYER_VAL_ALL_SHUFFLE;
136 value = OAL_PLAYER_VAL_GROUP_SHUFFLE;
139 BT_ERR("Invalid shuffel mode");
140 return BLUETOOTH_ERROR_INTERNAL;
143 result = avrcp_set_property(AVRCP_SHUFFLE, value);
144 if (result != OAL_STATUS_SUCCESS) {
145 BT_ERR("avrcp_set_property failed");
146 return _bt_convert_oal_status_to_bt_error(result);
150 return BLUETOOTH_ERROR_NONE;
153 static int __bt_avrcp_set_scan_mode(media_player_scan_status scan_status)
160 switch (scan_status) {
171 BT_ERR("Invalid scan mode");
172 return BLUETOOTH_ERROR_INTERNAL;
175 result = avrcp_set_property(AVRCP_SCAN, value);
176 if (result != OAL_STATUS_SUCCESS) {
177 BT_ERR("avrcp_set_property failed");
178 return _bt_convert_oal_status_to_bt_error(result);
182 return BLUETOOTH_ERROR_NONE;
185 static int __bt_avrcp_set_player_status(media_player_status status)
194 value = OAL_PLAYSTATE_STOPPED;
197 value = OAL_PLAYSTATE_PLAYING;
200 value = OAL_PLAYSTATE_PAUSED;
202 case STATUS_FORWARD_SEEK:
203 value = OAL_PLAYSTATE_FWD_SEEK;
205 case STATUS_REVERSE_SEEK:
206 value = OAL_PLAYSTATE_REV_SEEK;
209 value = OAL_PLAYSTATE_ERROR;
213 return BLUETOOTH_ERROR_INTERNAL;
216 result = avrcp_set_property(AVRCP_STATUS, value);
217 if (result != OAL_STATUS_SUCCESS) {
218 BT_ERR("avrcp_set_property failed");
219 return _bt_convert_oal_status_to_bt_error(result);
223 return BLUETOOTH_ERROR_NONE;
226 static int __bt_avrcp_set_play_position(unsigned int position)
232 result = avrcp_set_property(AVRCP_POSITION, position);
233 if (result != OAL_STATUS_SUCCESS) {
234 BT_ERR("avrcp_set_property failed");
235 return _bt_convert_oal_status_to_bt_error(result);
239 return BLUETOOTH_ERROR_NONE;
242 int _bt_avrcp_connect_remote_ctrl(bluetooth_device_address_t *address)
244 oal_status_t status = OAL_STATUS_SUCCESS;
245 int result = BLUETOOTH_ERROR_NONE;
250 memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
251 status = avrcp_tg_connect(&bdaddr);
252 if (status != OAL_STATUS_SUCCESS) {
253 BT_ERR("Connection could not be established, err: [%d]", status);
254 result = _bt_convert_oal_status_to_bt_error(status);
261 int _bt_avrcp_disconnect_remote_ctrl(bluetooth_device_address_t *address)
263 oal_status_t status = OAL_STATUS_SUCCESS;
264 int result = BLUETOOTH_ERROR_NONE;
269 memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
270 status = avrcp_tg_disconnect(&bdaddr);
271 if (status != OAL_STATUS_SUCCESS) {
272 BT_ERR("DisConnection err: [%d]", status);
273 result = _bt_convert_oal_status_to_bt_error(status);
280 int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
283 oal_media_metadata_attributes_t media_attr;
287 retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
289 g_strlcpy(media_attr.title, meta_data->title, OAL_MAX_ATTR_STR_LEN);
290 g_strlcpy(media_attr.artist, meta_data->artist, OAL_MAX_ATTR_STR_LEN);
291 g_strlcpy(media_attr.album, meta_data->album, OAL_MAX_ATTR_STR_LEN);
292 g_strlcpy(media_attr.genre, meta_data->genre, OAL_MAX_ATTR_STR_LEN);
293 media_attr.total_tracks = meta_data->total_tracks;
294 media_attr.number = meta_data->number;
295 media_attr.duration = meta_data->duration;
297 result = avrcp_set_track_info(&media_attr);
298 if (result != OAL_STATUS_SUCCESS) {
299 BT_ERR("hid_connect error: [%d]", result);
300 return _bt_convert_oal_status_to_bt_error(result);
304 return BLUETOOTH_ERROR_NONE;
307 int _bt_avrcp_target_notify_volume(bluetooth_device_address_t *address, unsigned int volume)
309 int result = BLUETOOTH_ERROR_NONE;
312 memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
314 result = avrcp_tg_set_volume(&bdaddr, volume);
315 if (result != OAL_STATUS_SUCCESS) {
316 BT_ERR("hid_connect error: [%d]", result);
317 return _bt_convert_oal_status_to_bt_error(result);
320 return BLUETOOTH_ERROR_NONE;
323 int _bt_avrcp_target_get_volume(bluetooth_device_address_t *address, unsigned int *volume)
325 int result = BLUETOOTH_ERROR_NONE;
328 memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
330 result = avrcp_tg_get_volume(&bdaddr, volume);
331 if (result != OAL_STATUS_SUCCESS) {
332 BT_ERR("hid_connect error: [%d]", result);
333 return _bt_convert_oal_status_to_bt_error(result);
336 return BLUETOOTH_ERROR_NONE;
339 int _bt_avrcp_set_properties(media_player_settings_t *properties)
344 ret = __bt_avrcp_set_equalizer(properties->equalizer);
345 if (ret != BLUETOOTH_ERROR_NONE) {
346 BT_ERR("__bt_avrcp_set_equalizer failed");
350 ret = __bt_avrcp_set_repeat_status(properties->repeat);
351 if (ret != BLUETOOTH_ERROR_NONE) {
352 BT_ERR("__bt_avrcp_set_repeat_status failed");
356 ret = __bt_avrcp_set_shuffel_mode(properties->shuffle);
357 if (ret != BLUETOOTH_ERROR_NONE) {
358 BT_ERR("__bt_avrcp_set_shuffel_mode failed");
362 ret = __bt_avrcp_set_scan_mode(properties->scan);
363 if (ret != BLUETOOTH_ERROR_NONE) {
364 BT_ERR("__bt_avrcp_set_scan_mode failed");
368 ret = __bt_avrcp_set_play_position(properties->position);
369 if (ret != BLUETOOTH_ERROR_NONE) {
370 BT_ERR("__bt_avrcp_set_play_position failed");
374 ret = _bt_avrcp_set_track_info(&(properties->metadata));
375 if (ret != BLUETOOTH_ERROR_NONE) {
376 BT_ERR("_bt_avrcp_set_track_info failed");
384 int _bt_avrcp_set_property(int type, unsigned int value)
392 ret = __bt_avrcp_set_equalizer(value);
395 ret = __bt_avrcp_set_repeat_status(value);
398 ret = __bt_avrcp_set_shuffel_mode(value);
401 ret = __bt_avrcp_set_scan_mode(value);
404 ret = __bt_avrcp_set_player_status(value);
407 ret = __bt_avrcp_set_play_position(value);
410 BT_DBG("Invalid Type");
411 return BLUETOOTH_ERROR_INTERNAL;
414 if (ret != BLUETOOTH_ERROR_NONE) {
415 BT_ERR("set property: %.2X failed", type);
420 return BLUETOOTH_ERROR_NONE;
423 static void __handle_player_property_equalizer(unsigned char *value)
425 media_player_equalizer_status equalizer;
429 equalizer = EQUALIZER_ON;
432 equalizer = EQUALIZER_OFF;
435 BT_ERR("Unknown equalizer setting");
436 equalizer = EQUALIZER_INVALID;
439 _bt_send_event(BT_AVRCP_EVENT,
440 BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
441 g_variant_new("(u)", equalizer));
444 static void __handle_player_property_repeat(unsigned char *value)
446 media_player_repeat_status status;
449 case OAL_PLAYER_VAL_OFF_REPEAT:
450 status = REPEAT_MODE_OFF;
452 case OAL_PLAYER_VAL_SINGLE_REPEAT:
453 status = REPEAT_SINGLE_TRACK;
455 case OAL_PLAYER_VAL_GROUP_REPEAT:
456 status = REPEAT_GROUP;
458 case OAL_PLAYER_VAL_ALL_REPEAT:
459 status = REPEAT_ALL_TRACK;
462 BT_ERR("Invalid repeat setting");
463 status = REPEAT_INVALID;
466 _bt_send_event(BT_AVRCP_EVENT,
467 BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
468 g_variant_new("(u)", status));
471 static void __handle_player_property_shuffle(unsigned char *value)
473 media_player_shuffle_status status;
476 case OAL_PLAYER_VAL_OFF_SHUFFLE:
477 status = SHUFFLE_MODE_OFF;
479 case OAL_PLAYER_VAL_GROUP_SHUFFLE:
480 status = SHUFFLE_GROUP;
482 case OAL_PLAYER_VAL_ALL_SHUFFLE:
483 status = SHUFFLE_ALL_TRACK;
486 BT_ERR("Invalid shuffle setting");
487 status = SHUFFLE_INVALID;
490 _bt_send_event(BT_AVRCP_EVENT,
491 BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
492 g_variant_new("(u)", status));
495 static void __handle_player_property_scan(unsigned char *value)
497 media_player_scan_status status;
501 status = SCAN_MODE_OFF;
504 status = SCAN_ALL_TRACK;
510 BT_ERR("Unknown scan setting");
511 status = SCAN_INVALID;
514 _bt_send_event(BT_AVRCP_EVENT,
515 BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
516 g_variant_new("(u)", status));
519 static void __handle_transport_property_delay(unsigned int *value)
525 _bt_send_event(BT_AVRCP_EVENT,
526 BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED,
527 g_variant_new("(u)", delay));
532 static void __handle_transport_property_volume(unsigned int avrcp_volume)
534 _bt_audio_handle_transport_volume_changed(avrcp_volume);
537 static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
539 int result = BLUETOOTH_ERROR_NONE;
540 char address[BT_ADDRESS_STRING_SIZE];
541 GVariant *param = NULL;
542 invocation_info_t *req_info;
544 _bt_convert_addr_type_to_string(address, bdaddr->addr);
546 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED) {
547 /* Reply to async request for AVRCP Target connect, if any */
548 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
550 /* Check if request for AVRCP Target disconnect failed */
551 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
553 result = BLUETOOTH_ERROR_INTERNAL;
556 /* Reply to async request for AVRCP Target disconnect, if any */
557 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
559 /* Check if request for AVRCP Target connect failed */
560 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
562 result = BLUETOOTH_ERROR_INTERNAL;
566 if (NULL != req_info) {
569 /* Create out param */
570 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
571 g_array_append_vals(out_param, address, sizeof(address));
573 _bt_service_method_return(req_info->context, out_param, result);
574 g_array_free(out_param, TRUE);
575 _bt_free_info_from_invocation_list(req_info);
578 if (BLUETOOTH_ERROR_NONE == result) {
579 param = g_variant_new("(is)", result, address);
580 /* Send event to application */
581 _bt_send_event(BT_AVRCP_EVENT, event, param);
583 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED)
584 /* Connected: Add AVRCP TARGET to headset list */
585 _bt_add_headset_to_list(BT_AVRCP_TARGET, BT_STATE_CONNECTED, address);
587 /* Disconnected: Remove AVRCP TARGET from headset list */
588 _bt_remove_headset_from_list(BT_AVRCP_TARGET, address);
592 static void __handle_avrcp_target_events(int event_type, gpointer event_data)
594 switch (event_type) {
595 case OAL_EVENT_AVRCP_CONNECTED:
596 __handle_avrcp_connection_event(
597 BLUETOOTH_EVENT_AVRCP_CONNECTED,
598 (bt_address_t *)event_data);
599 BT_PERMANENT_LOG("Connected AVRCP tg");
601 case OAL_EVENT_AVRCP_DISCONNECTED:
602 __handle_avrcp_connection_event(
603 BLUETOOTH_EVENT_AVRCP_DISCONNECTED,
604 (bt_address_t *)event_data);
605 BT_PERMANENT_LOG("Disconnected AVRCP tg");
607 case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
608 __handle_player_property_equalizer((unsigned char *)event_data);
610 case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
611 __handle_player_property_repeat((unsigned char *)event_data);
613 case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
614 __handle_player_property_shuffle((unsigned char *)event_data);
616 case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
617 __handle_player_property_scan((unsigned char *)event_data);
619 case OAL_EVENT_AVRCP_REMOTE_FEATURES:
621 case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED: {
622 oal_avrcp_volume_mute_t *volume_mute = (oal_avrcp_volume_mute_t *)event_data;
625 __handle_transport_property_volume(volume_mute->volume);
628 case OAL_EVENT_AVRCP_DELAY_CHANGED:
629 __handle_transport_property_delay((unsigned int *)event_data);
632 BT_ERR("Unhandled AVRCP target event: %d", event_type);
636 int _bt_service_avrcp_enable(void)
638 oal_status_t status = OAL_STATUS_SUCCESS;
640 status = avrcp_enable();
641 if (OAL_STATUS_SUCCESS != status) {
642 BT_ERR("Failed to initialize Bluetooth AVRCP Target Profile, status: %d", status);
643 return _bt_convert_oal_status_to_bt_error(status);
646 /* Register AVRCP target event handler */
647 _bt_service_register_event_handler_callback(BT_AVRCP_MODULE, __handle_avrcp_target_events);
649 return BLUETOOTH_ERROR_NONE;
652 int _bt_service_avrcp_disable(void)
654 oal_status_t status = OAL_STATUS_SUCCESS;
656 status = avrcp_disable();
657 if (OAL_STATUS_SUCCESS != status) {
658 BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
659 return _bt_convert_oal_status_to_bt_error(status);
662 /* Register AVRCP target event handler */
663 _bt_service_unregister_event_handler_callback(BT_AVRCP_MODULE);
665 return BLUETOOTH_ERROR_NONE;