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 BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
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 = BLUETOOTH_ERROR_INTERNAL;
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 = BLUETOOTH_ERROR_INTERNAL;
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 BLUETOOTH_ERROR_INTERNAL;
304 return BLUETOOTH_ERROR_NONE;
307 int _bt_avrcp_set_properties(media_player_settings_t *properties)
312 ret = __bt_avrcp_set_equalizer(properties->equalizer);
313 if (ret != BLUETOOTH_ERROR_NONE) {
314 BT_ERR("__bt_avrcp_set_equalizer failed");
318 ret = __bt_avrcp_set_repeat_status(properties->repeat);
319 if (ret != BLUETOOTH_ERROR_NONE) {
320 BT_ERR("__bt_avrcp_set_repeat_status failed");
324 ret = __bt_avrcp_set_shuffel_mode(properties->shuffle);
325 if (ret != BLUETOOTH_ERROR_NONE) {
326 BT_ERR("__bt_avrcp_set_shuffel_mode failed");
330 ret = __bt_avrcp_set_scan_mode(properties->scan);
331 if (ret != BLUETOOTH_ERROR_NONE) {
332 BT_ERR("__bt_avrcp_set_scan_mode failed");
336 ret = __bt_avrcp_set_play_position(properties->position);
337 if (ret != BLUETOOTH_ERROR_NONE) {
338 BT_ERR("__bt_avrcp_set_play_position failed");
342 ret = _bt_avrcp_set_track_info(&(properties->metadata));
343 if (ret != BLUETOOTH_ERROR_NONE) {
344 BT_ERR("_bt_avrcp_set_track_info failed");
352 int _bt_avrcp_set_property(int type, unsigned int value)
360 ret = __bt_avrcp_set_equalizer(value);
363 ret = __bt_avrcp_set_repeat_status(value);
366 ret = __bt_avrcp_set_shuffel_mode(value);
369 ret = __bt_avrcp_set_scan_mode(value);
372 ret = __bt_avrcp_set_player_status(value);
375 ret = __bt_avrcp_set_play_position(value);
378 BT_DBG("Invalid Type");
379 return BLUETOOTH_ERROR_INTERNAL;
382 if (ret != BLUETOOTH_ERROR_NONE) {
383 BT_ERR("set property: %.2X failed", type);
388 return BLUETOOTH_ERROR_NONE;
391 static void __handle_player_property_equalizer(unsigned char *value)
393 media_player_equalizer_status equalizer;
397 equalizer = EQUALIZER_ON;
400 equalizer = EQUALIZER_OFF;
403 BT_ERR("Unknown equalizer setting");
404 equalizer = EQUALIZER_INVALID;
407 _bt_send_event(BT_AVRCP_EVENT,
408 BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
409 g_variant_new("(u)", equalizer));
412 static void __handle_player_property_repeat(unsigned char *value)
414 media_player_repeat_status status;
417 case OAL_PLAYER_VAL_OFF_REPEAT:
418 status = REPEAT_MODE_OFF;
420 case OAL_PLAYER_VAL_SINGLE_REPEAT:
421 status = REPEAT_SINGLE_TRACK;
423 case OAL_PLAYER_VAL_GROUP_REPEAT:
424 status = REPEAT_GROUP;
426 case OAL_PLAYER_VAL_ALL_REPEAT:
427 status = REPEAT_ALL_TRACK;
430 BT_ERR("Invalid repeat setting");
431 status = REPEAT_INVALID;
434 _bt_send_event(BT_AVRCP_EVENT,
435 BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
436 g_variant_new("(u)", status));
439 static void __handle_player_property_shuffle(unsigned char *value)
441 media_player_shuffle_status status;
444 case OAL_PLAYER_VAL_OFF_SHUFFLE:
445 status = SHUFFLE_MODE_OFF;
447 case OAL_PLAYER_VAL_GROUP_SHUFFLE:
448 status = SHUFFLE_GROUP;
450 case OAL_PLAYER_VAL_ALL_SHUFFLE:
451 status = SHUFFLE_ALL_TRACK;
454 BT_ERR("Invalid shuffle setting");
455 status = SHUFFLE_INVALID;
458 _bt_send_event(BT_AVRCP_EVENT,
459 BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
460 g_variant_new("(u)", status));
463 static void __handle_player_property_scan(unsigned char *value)
465 media_player_scan_status status;
469 status = SCAN_MODE_OFF;
472 status = SCAN_ALL_TRACK;
478 BT_ERR("Unknown scan setting");
479 status = SCAN_INVALID;
482 _bt_send_event(BT_AVRCP_EVENT,
483 BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
484 g_variant_new("(u)", status));
487 static void __handle_transport_property_delay(unsigned int *value)
493 _bt_send_event(BT_AVRCP_EVENT,
494 BLUETOOTH_EVENT_AVRCP_DELAY_CHANGED,
495 g_variant_new("(u)", delay));
500 static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
502 int result = BLUETOOTH_ERROR_NONE;
503 char address[BT_ADDRESS_STRING_SIZE];
504 GVariant *param = NULL;
505 invocation_info_t *req_info;
507 _bt_convert_addr_type_to_string(address, bdaddr->addr);
509 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED) {
510 /* Reply to async request for AVRCP Target connect, if any */
511 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
513 /* Check if request for AVRCP Target disconnect failed */
514 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
516 result = BLUETOOTH_ERROR_INTERNAL;
519 /* Reply to async request for AVRCP Target disconnect, if any */
520 req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
522 /* Check if request for AVRCP Target connect failed */
523 req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
525 result = BLUETOOTH_ERROR_INTERNAL;
529 if (NULL != req_info) {
532 /* Create out param */
533 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
534 g_array_append_vals(out_param, address, sizeof(address));
536 _bt_service_method_return(req_info->context, out_param, result);
537 g_array_free(out_param, TRUE);
538 g_free(req_info->user_data);
539 _bt_free_info_from_invocation_list(req_info);
542 if (BLUETOOTH_ERROR_NONE == result) {
543 param = g_variant_new("(is)", result, address);
544 /* Send event to application */
545 _bt_send_event(BT_AVRCP_EVENT, event, param);
547 if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED)
548 /* Connected: Add AVRCP TARGET to headset list */
549 _bt_add_headset_to_list(BT_AVRCP_TARGET, BT_STATE_CONNECTED, address);
551 /* Disconnected: Remove AVRCP TARGET from headset list */
552 _bt_remove_headset_from_list(BT_AVRCP_TARGET, address);
556 static void __handle_avrcp_target_events(int event_type, gpointer event_data)
558 switch (event_type) {
559 case OAL_EVENT_AVRCP_CONNECTED:
560 __handle_avrcp_connection_event(
561 BLUETOOTH_EVENT_AVRCP_CONNECTED,
562 (bt_address_t *)event_data);
563 BT_PERMANENT_LOG("Connected AVRCP tg");
565 case OAL_EVENT_AVRCP_DISCONNECTED:
566 __handle_avrcp_connection_event(
567 BLUETOOTH_EVENT_AVRCP_DISCONNECTED,
568 (bt_address_t *)event_data);
569 BT_PERMANENT_LOG("Disconnected AVRCP tg");
571 case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
572 __handle_player_property_equalizer((unsigned char *)event_data);
574 case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
575 __handle_player_property_repeat((unsigned char *)event_data);
577 case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
578 __handle_player_property_shuffle((unsigned char *)event_data);
580 case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
581 __handle_player_property_scan((unsigned char *)event_data);
583 case OAL_EVENT_AVRCP_REMOTE_FEATURES:
585 case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED:
587 case OAL_EVENT_AVRCP_DELAY_CHANGED:
588 __handle_transport_property_delay((unsigned int *)event_data);
591 BT_ERR("Unhandled AVRCP target event: %d", event_type);
595 int _bt_service_avrcp_enable(void)
597 oal_status_t status = OAL_STATUS_SUCCESS;
599 status = avrcp_enable();
600 if (OAL_STATUS_SUCCESS != status) {
601 BT_ERR("Failed to initialize Bluetooth AVRCP Target Profile, status: %d", status);
602 return BLUETOOTH_ERROR_INTERNAL;
605 /* Register AVRCP target event handler */
606 _bt_service_register_event_handler_callback(BT_AVRCP_MODULE, __handle_avrcp_target_events);
608 return BLUETOOTH_ERROR_NONE;
611 int _bt_service_avrcp_disable(void)
613 oal_status_t status = OAL_STATUS_SUCCESS;
615 status = avrcp_disable();
616 if (OAL_STATUS_SUCCESS != status) {
617 BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
618 return BLUETOOTH_ERROR_INTERNAL;
621 /* Register AVRCP target event handler */
622 _bt_service_unregister_event_handler_callback(BT_AVRCP_MODULE);
624 return BLUETOOTH_ERROR_NONE;