[Adapt:Frwk] Implement AVRCP TARGET role BT-FRWK 79/117179/1
authorAtul Rai <a.rai@samsung.com>
Fri, 3 Mar 2017 03:53:47 +0000 (09:23 +0530)
committerAtul Rai <a.rai@samsung.com>
Fri, 3 Mar 2017 03:53:47 +0000 (09:23 +0530)
This patch adds bt-service and bt-api implementation for
AVRCP TARGET role.

Change-Id: I75362b6240d461107c4a4b2f6ae4715c8cab47e5
Signed-off-by: Atul Rai <a.rai@samsung.com>
bt-api/bt-request-sender.c
bt-service-adaptation/CMakeLists.txt
bt-service-adaptation/services/adapter/bt-service-core-adapter.c
bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-ctrl.c [moved from bt-service-adaptation/services/audio/avrcp_ctrl/bt-service-avrcp-ctrl.c with 100% similarity]
bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c [new file with mode: 0644]
bt-service-adaptation/services/audio/bt-service-audio.c
bt-service-adaptation/services/bt-request-handler.c
bt-service-adaptation/services/bt-service-event-receiver.c
bt-service-adaptation/services/include/bt-service-audio-common.h
bt-service-adaptation/services/include/bt-service-avrcp-tg.h [new file with mode: 0755]
bt-service-adaptation/services/include/bt-service-event-receiver.h

index 943fd2a..da58dd5 100644 (file)
@@ -195,6 +195,18 @@ void _bt_get_event_info(int service_function, GArray *output,
                *param_data = &g_array_index(output,
                                bluetooth_rfcomm_connection_t, 0);
                break;
+       case BT_AVRCP_TARGET_CONNECT:
+               *event_type = BT_AVRCP_EVENT;
+               *event = BLUETOOTH_EVENT_AVRCP_CONNECTED;
+               ret_if(output == NULL);
+               *param_data = &g_array_index(output, char, 0);
+               break;
+       case BT_AVRCP_TARGET_DISCONNECT:
+               *event_type = BT_AVRCP_EVENT;
+               *event = BLUETOOTH_EVENT_AVRCP_DISCONNECTED;
+               ret_if(output == NULL);
+               *param_data = &g_array_index(output, char, 0);
+               break;
        case BT_AVRCP_CONTROL_CONNECT:
                *event_type = BT_AVRCP_CONTROL_EVENT;
                *event = BLUETOOTH_EVENT_AVRCP_CONTROL_CONNECTED;
@@ -376,6 +388,9 @@ static void __send_request_cb(GDBusProxy *proxy,
        } else if (event_type == BT_HDP_EVENT) {
                ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
                        &bt_event, cb_data->user_data);
+       } else if (event_type == BT_AVRCP_EVENT) {
+               ((bluetooth_cb_func_ptr)cb_data->cb)(bt_event.event,
+                       &bt_event, cb_data->user_data);
        } else {
                BT_INFO("Not handled event type : %d", event_type);
        }
index cbfbb8e..5799aa4 100644 (file)
@@ -22,7 +22,8 @@ marshal.c
 ./services/audio/a2dp_src/bt-service-a2dp-src.c
 ./services/audio/a2dp_sink/bt-service-a2dp-sink.c
 ./services/health/bt-service-hdp.c
-./services/audio/avrcp_ctrl/bt-service-avrcp-ctrl.c
+./services/audio/avrcp/bt-service-avrcp-tg.c
+./services/audio/avrcp/bt-service-avrcp-ctrl.c
 )
 
 IF("${CMAKE_BUILD_TYPE}" STREQUAL "")
index a0db55e..5c821e6 100644 (file)
@@ -710,6 +710,14 @@ static int __bt_init_profiles()
                BT_ERR("_bt_audio_initialize(BT_A2DP_SOURCE_MODULE) Failed");
                return ret;
        }
+
+       /* Initialize AVRCP Target */
+       ret = _bt_audio_initialize(BT_AVRCP_MODULE);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("_bt_audio_initialize(BT_AVRCP_MODULE) Failed");
+               return ret;
+       }
+
        /* Initialize A2DP Sink */
        ret = _bt_audio_initialize(BT_A2DP_SINK_MODULE);
        if (ret != BLUETOOTH_ERROR_NONE) {
diff --git a/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c b/bt-service-adaptation/services/audio/avrcp/bt-service-avrcp-tg.c
new file mode 100644 (file)
index 0000000..c23b348
--- /dev/null
@@ -0,0 +1,608 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <gio/gio.h>
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <syspopup_caller.h>
+#include <dbus/dbus.h>
+
+#include <oal-avrcp-tg.h>
+
+#include "bluetooth-api.h"
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-avrcp-tg.h"
+#include "bt-service-event.h"
+#include "bt-service-event-receiver.h"
+#include "bt-service-audio-common.h"
+#include "bt-service-util.h"
+
+static invocation_info_t* __bt_get_request_info(int service_function, char *address)
+{
+       GSList *l;
+       invocation_info_t *req_info = NULL;
+
+       BT_DBG("+");
+
+       retv_if(NULL == address, FALSE);
+
+       /* Get method invocation context */
+       for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
+               req_info = l->data;
+               if (req_info == NULL || req_info->service_function != service_function)
+                       continue;
+
+               if (!strncasecmp((char *)req_info->user_data, address, BT_ADDRESS_STRING_SIZE))
+                       return req_info;
+       }
+
+       return NULL;
+}
+
+static int __bt_avrcp_set_equalizer(media_player_equalizer_status equalizer)
+{
+       unsigned int value;
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       switch (equalizer) {
+       case EQUALIZER_ON:
+               value = 0x01;
+               break;
+       case EQUALIZER_OFF:
+               value = 0x02;
+               break;
+       default:
+               BT_ERR("Invalid Equalizer state");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       result = avrcp_set_property(AVRCP_EQUALIZER, value);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_avrcp_set_repeat_status(media_player_repeat_status repeat_status)
+{
+       unsigned int value;
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       switch (repeat_status) {
+       case REPEAT_MODE_OFF:
+               value = OAL_PLAYER_VAL_OFF_REPEAT;
+               break;
+       case REPEAT_SINGLE_TRACK:
+               value = OAL_PLAYER_VAL_SINGLE_REPEAT;
+               break;
+       case REPEAT_ALL_TRACK:
+               value = OAL_PLAYER_VAL_ALL_REPEAT;
+               break;
+       case REPEAT_GROUP:
+               value = OAL_PLAYER_VAL_GROUP_REPEAT;
+               break;
+       default:
+               BT_ERR("Invalid repeat status");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       result = avrcp_set_property(AVRCP_REPEAT, value);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_avrcp_set_shuffel_mode(media_player_shuffle_status shuffel)
+{
+       unsigned int value;
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       switch (shuffel) {
+       case SHUFFLE_MODE_OFF:
+               value = OAL_PLAYER_VAL_OFF_SHUFFLE;
+               break;
+       case SHUFFLE_ALL_TRACK:
+               value = OAL_PLAYER_VAL_ALL_SHUFFLE;
+               break;
+       case SHUFFLE_GROUP:
+               value = OAL_PLAYER_VAL_GROUP_SHUFFLE;
+               break;
+       default:
+               BT_ERR("Invalid shuffel mode");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       result = avrcp_set_property(AVRCP_SHUFFLE, value);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_avrcp_set_scan_mode(media_player_scan_status scan_status)
+{
+       unsigned int value;
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       switch (scan_status) {
+       case SCAN_MODE_OFF:
+               value = 0x01;
+               break;
+       case SCAN_ALL_TRACK:
+               value = 0x02;
+               break;
+       case SCAN_GROUP:
+               value = 0x03;
+               break;
+       default:
+               BT_ERR("Invalid scan mode");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       result = avrcp_set_property(AVRCP_SCAN, value);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_avrcp_set_player_status(media_player_status status)
+{
+       unsigned int value;
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       switch (status) {
+       case STATUS_STOPPED:
+               value = OAL_PLAYSTATE_STOPPED;
+               break;
+       case STATUS_PLAYING:
+               value = OAL_PLAYSTATE_PLAYING;
+               break;
+       case STATUS_PAUSED:
+               value = OAL_PLAYSTATE_PAUSED;
+               break;
+       case STATUS_FORWARD_SEEK:
+               value = OAL_PLAYSTATE_FWD_SEEK;
+               break;
+       case STATUS_REVERSE_SEEK:
+               value = OAL_PLAYSTATE_REV_SEEK;
+               break;
+       case STATUS_ERROR:
+               value = OAL_PLAYSTATE_ERROR;
+               break;
+       default:
+               BT_ERR("Invalid ");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       result = avrcp_set_property(AVRCP_STATUS, value);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static int __bt_avrcp_set_play_position(unsigned int position)
+{
+       oal_status_t result;
+
+       BT_DBG("+");
+
+       result = avrcp_set_property(AVRCP_POSITION, position);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("avrcp_set_property failed");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_avrcp_connect_remote_ctrl(bluetooth_device_address_t *address)
+{
+       oal_status_t status = OAL_STATUS_SUCCESS;
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_address_t bdaddr;
+
+       BT_DBG("+");
+
+       memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+       status = avrcp_tg_connect(&bdaddr);
+       if (status != OAL_STATUS_SUCCESS) {
+               BT_ERR("Connection could not be established, err: [%d]", status);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return result;
+}
+
+int _bt_avrcp_disconnect_remote_ctrl(bluetooth_device_address_t *address)
+{
+       oal_status_t status = OAL_STATUS_SUCCESS;
+       int result = BLUETOOTH_ERROR_NONE;
+       bt_address_t bdaddr;
+
+       BT_DBG("+");
+
+       memcpy(bdaddr.addr, address->addr, BT_ADDRESS_BYTES_NUM);
+       status = avrcp_tg_disconnect(&bdaddr);
+       if (status != OAL_STATUS_SUCCESS) {
+               BT_ERR("DisConnection err: [%d]", status);
+               result = BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return result;
+}
+
+int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data)
+{
+       oal_status_t result;
+       oal_media_metadata_attributes_t media_attr;
+
+       BT_DBG("+");
+
+       retv_if(meta_data == NULL, BLUETOOTH_ERROR_INTERNAL);
+
+       g_strlcpy(media_attr.title, meta_data->title, OAL_MAX_ATTR_STR_LEN);
+       g_strlcpy(media_attr.artist, meta_data->artist, OAL_MAX_ATTR_STR_LEN);
+       g_strlcpy(media_attr.album, meta_data->album, OAL_MAX_ATTR_STR_LEN);
+       g_strlcpy(media_attr.genre, meta_data->genre, OAL_MAX_ATTR_STR_LEN);
+       media_attr.total_tracks = meta_data->total_tracks;
+       media_attr.number = meta_data->number;
+       media_attr.duration = meta_data->duration;
+
+       result = avrcp_set_track_info(&media_attr);
+       if (result != OAL_STATUS_SUCCESS) {
+               BT_ERR("hid_connect error: [%d]", result);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_avrcp_set_properties(media_player_settings_t *properties)
+{
+       int ret;
+       BT_DBG("+");
+
+       ret = __bt_avrcp_set_equalizer(properties->equalizer);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("__bt_avrcp_set_equalizer failed");
+               return ret;
+       }
+
+       ret = __bt_avrcp_set_repeat_status(properties->repeat);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("__bt_avrcp_set_repeat_status failed");
+               return ret;
+       }
+
+       ret = __bt_avrcp_set_shuffel_mode(properties->shuffle);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("__bt_avrcp_set_shuffel_mode failed");
+               return ret;
+       }
+
+       ret = __bt_avrcp_set_scan_mode(properties->scan);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("__bt_avrcp_set_scan_mode failed");
+               return ret;
+       }
+
+       ret = __bt_avrcp_set_play_position(properties->position);
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("__bt_avrcp_set_play_position failed");
+               return ret;
+       }
+
+       ret = _bt_avrcp_set_track_info(&(properties->metadata));
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("_bt_avrcp_set_track_info failed");
+               return ret;
+       }
+
+       BT_DBG("-");
+       return ret;
+}
+
+int _bt_avrcp_set_property(int type, unsigned int value)
+{
+       int ret;
+
+       BT_DBG("+");
+
+       switch (type) {
+       case EQUALIZER:
+               ret = __bt_avrcp_set_equalizer(value);
+               break;
+       case REPEAT:
+               ret = __bt_avrcp_set_repeat_status(value);
+               break;
+       case SHUFFLE:
+               ret = __bt_avrcp_set_shuffel_mode(value);
+               break;
+       case SCAN:
+               ret = __bt_avrcp_set_scan_mode(value);
+               break;
+       case STATUS:
+               ret = __bt_avrcp_set_player_status(value);
+               break;
+       case POSITION:
+               ret = __bt_avrcp_set_play_position(value);
+               break;
+       default:
+               BT_DBG("Invalid Type");
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       if (ret != BLUETOOTH_ERROR_NONE) {
+               BT_ERR("set property: %.2X failed", type);
+               return ret;
+       }
+
+       BT_DBG("-");
+       return BLUETOOTH_ERROR_NONE;
+}
+
+static void __handle_player_property_equalizer(unsigned char *value)
+{
+       media_player_equalizer_status equalizer;
+
+       switch (*value) {
+       case 0x01:
+               equalizer = EQUALIZER_ON;
+               break;
+       case 0x02:
+               equalizer = EQUALIZER_OFF;
+               break;
+       default:
+               BT_ERR("Unknown equalizer setting");
+               equalizer = EQUALIZER_INVALID;
+       }
+
+       _bt_send_event(BT_AVRCP_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_SETTING_EQUALIZER_STATUS,
+                       g_variant_new("(u)", equalizer));
+}
+
+static void __handle_player_property_repeat(unsigned char *value)
+{
+       media_player_repeat_status status;
+
+       switch (*value) {
+       case OAL_PLAYER_VAL_OFF_REPEAT:
+               status = REPEAT_MODE_OFF;
+               break;
+       case OAL_PLAYER_VAL_SINGLE_REPEAT:
+               status = REPEAT_SINGLE_TRACK;
+               break;
+       case OAL_PLAYER_VAL_GROUP_REPEAT:
+               status = REPEAT_GROUP;
+               break;
+       case OAL_PLAYER_VAL_ALL_REPEAT:
+               status = REPEAT_ALL_TRACK;
+               break;
+       default:
+               BT_ERR("Invalid repeat setting");
+               status = REPEAT_INVALID;
+       }
+
+       _bt_send_event(BT_AVRCP_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_SETTING_REPEAT_STATUS,
+                       g_variant_new("(u)", status));
+}
+
+static void __handle_player_property_shuffle(unsigned char *value)
+{
+       media_player_shuffle_status status;
+
+       switch (*value) {
+       case OAL_PLAYER_VAL_OFF_SHUFFLE:
+               status = SHUFFLE_MODE_OFF;
+               break;
+       case OAL_PLAYER_VAL_GROUP_SHUFFLE:
+               status = SHUFFLE_GROUP;
+               break;
+       case OAL_PLAYER_VAL_ALL_SHUFFLE:
+               status = SHUFFLE_ALL_TRACK;
+               break;
+       default:
+               BT_ERR("Invalid shuffle setting");
+               status = SHUFFLE_INVALID;
+       }
+
+       _bt_send_event(BT_AVRCP_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_SETTING_SHUFFLE_STATUS,
+                       g_variant_new("(u)", status));
+}
+
+static void __handle_player_property_scan(unsigned char *value)
+{
+       media_player_scan_status status;
+
+       switch (*value) {
+       case 0x01:
+               status = SCAN_MODE_OFF;
+               break;
+       case 0x02:
+               status = SCAN_ALL_TRACK;
+               break;
+       case 0x03:
+               status = SCAN_GROUP;
+               break;
+       default:
+               BT_ERR("Unknown scan setting");
+               status = SCAN_INVALID;
+       }
+
+       _bt_send_event(BT_AVRCP_EVENT,
+                       BLUETOOTH_EVENT_AVRCP_SETTING_SCAN_STATUS,
+                       g_variant_new("(u)", status));
+}
+
+static void __handle_avrcp_connection_event(int event, bt_address_t *bdaddr)
+{
+       int result = BLUETOOTH_ERROR_NONE;
+       char address[BT_ADDRESS_STRING_SIZE];
+       GVariant *param = NULL;
+       invocation_info_t *req_info;
+
+       _bt_convert_addr_type_to_string(address, bdaddr->addr);
+
+       if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED) {
+               /* Reply to async request for AVRCP Target connect, if any */
+               req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
+               if (!req_info) {
+                       /* Check if request for AVRCP Target disconnect failed */
+                       req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
+                       if (req_info)
+                               result = BLUETOOTH_ERROR_INTERNAL;
+               }
+       } else {
+               /* Reply to async request for AVRCP Target disconnect, if any */
+               req_info = __bt_get_request_info(BT_AVRCP_TARGET_DISCONNECT, address);
+               if (!req_info) {
+                       /* Check if request for AVRCP Target connect failed */
+                       req_info = __bt_get_request_info(BT_AVRCP_TARGET_CONNECT, address);
+                       if (req_info)
+                               result = BLUETOOTH_ERROR_INTERNAL;
+               }
+       }
+
+       if (NULL != req_info) {
+               GArray *out_param;
+
+               /* Create out param */
+               out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
+               g_array_append_vals(out_param, address, sizeof(address));
+
+               _bt_service_method_return(req_info->context, out_param, result);
+               g_array_free(out_param, TRUE);
+               g_free(req_info->user_data);
+               _bt_free_info_from_invocation_list(req_info);
+       }
+
+       if (BLUETOOTH_ERROR_NONE == result) {
+               param = g_variant_new("(is)", result, address);
+               /* Send event to application */
+               _bt_send_event(BT_AVRCP_EVENT, event, param);
+
+               if (event == BLUETOOTH_EVENT_AVRCP_CONNECTED)
+                       /* Connected: Add AVRCP TARGET to headset list */
+                       _bt_add_headset_to_list(BT_AVRCP_TARGET, BT_STATE_CONNECTED, address);
+               else
+                       /* Disconnected: Remove AVRCP TARGET from headset list */
+                       _bt_remove_headset_from_list(BT_AVRCP_TARGET, address);
+       }
+}
+
+static void __handle_avrcp_target_events(int event_type, gpointer event_data)
+{
+       switch (event_type) {
+       case OAL_EVENT_AVRCP_CONNECTED:
+               __handle_avrcp_connection_event(
+                               BLUETOOTH_EVENT_AVRCP_CONNECTED,
+                               (bt_address_t *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_DISCONNECTED:
+               __handle_avrcp_connection_event(
+                               BLUETOOTH_EVENT_AVRCP_DISCONNECTED,
+                               (bt_address_t *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
+               __handle_player_property_equalizer((unsigned char *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
+               __handle_player_property_repeat((unsigned char *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
+               __handle_player_property_shuffle((unsigned char *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
+               __handle_player_property_scan((unsigned char *)event_data);
+               break;
+       case OAL_EVENT_AVRCP_REMOTE_FEATURES:
+               break;
+       case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED:
+               break;
+       default:
+               BT_ERR("Unhandled AVRCP target event: %d", event_type);
+       }
+}
+
+int _bt_service_avrcp_enable(void)
+{
+       oal_status_t status = OAL_STATUS_SUCCESS;
+
+       status = avrcp_enable();
+       if (OAL_STATUS_SUCCESS != status) {
+               BT_ERR("Failed to initialize Bluetooth AVRCP Target Profile, status: %d", status);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Register AVRCP target event handler */
+       _bt_service_register_event_handler_callback(BT_AVRCP_MODULE, __handle_avrcp_target_events);
+
+       return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_service_avrcp_disable(void)
+{
+       oal_status_t status = OAL_STATUS_SUCCESS;
+
+       status = avrcp_disable();
+       if (OAL_STATUS_SUCCESS != status) {
+               BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
+               return BLUETOOTH_ERROR_INTERNAL;
+       }
+
+       /* Register AVRCP target event handler */
+       _bt_service_unregister_event_handler_callback(BT_AVRCP_MODULE);
+
+       return BLUETOOTH_ERROR_NONE;
+}
index 3858117..87f740c 100644 (file)
@@ -37,6 +37,7 @@
 #include "bt-service-core-device.h"
 #include "bt-service-a2dp-src.h"
 #include "bt-service-a2dp-sink.h"
+#include "bt-service-avrcp-tg.h"
 #include "bt-service-avrcp-ctrl.h"
 #include "bt-service-hf.h"
 
@@ -75,6 +76,7 @@ static int __bt_is_headset_disconnecting(int type);
 
 static void __bt_audio_cleanup_resources(void);
 
+#if 0
 void _bt_headset_set_local_connection(gboolean value)
 {
        BT_INFO("setting connection_local to %d", value);
@@ -85,6 +87,7 @@ gboolean _bt_headset_get_local_connection()
 {
        return connection_local;
 }
+#endif
 
 void _bt_set_audio_wait_data_flag(gboolean flag)
 {
@@ -396,6 +399,9 @@ static int __bt_process_audio_profile_connect(bt_audio_type_t type, bluetooth_de
         case BT_AUDIO_A2DP:
                result = _bt_a2dp_connect_remote_sink(address);
                 break;
+        case BT_AVRCP_TARGET:
+               result = _bt_avrcp_connect_remote_ctrl(address);
+               break;
         case BT_AVRCP:
                result = _bt_avrcp_connect_remote_target(address);
                break;
@@ -408,7 +414,7 @@ static int __bt_process_audio_profile_connect(bt_audio_type_t type, bluetooth_de
         }
 
        if (result == BLUETOOTH_ERROR_NONE) {
-               _bt_headset_set_local_connection(TRUE);
+               //_bt_headset_set_local_connection(TRUE);
                /* Add data to the connected list */
                 _bt_add_headset_to_list(type, BT_STATE_CONNECTING, addr);
        } else {
@@ -435,6 +441,9 @@ static int __bt_process_audio_profile_disconnect(bt_audio_type_t type, bluetooth
         case BT_AUDIO_A2DP:
                result = _bt_a2dp_disconnect_remote_sink(address);
                 break;
+        case BT_AVRCP_TARGET:
+               result = _bt_avrcp_disconnect_remote_ctrl(address);
+               break;
         case BT_AVRCP:
                result = _bt_avrcp_disconnect_remote_target(address);
                break;
@@ -479,63 +488,62 @@ int _bt_audio_initialize(bt_service_module_t module)
        BT_INFO("_bt_audio_initialize: Module [%d]", module);
 
        switch (module) {
-               case BT_A2DP_SOURCE_MODULE:
-               {
-                       status = audio_enable(NULL, NULL);
-                       if (OAL_STATUS_SUCCESS != status) {
-                               BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
-                               return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       /* Register Audio module event handler */
-                       _bt_service_register_event_handler_callback(module, _bt_a2dp_source_event_handler);
-                       break;
-               }
-               case BT_A2DP_SINK_MODULE:
-               {
-                       status = a2dp_sink_enable(NULL, NULL);
-                       if (status != OAL_STATUS_SUCCESS) {
-                               BT_ERR("Failed to initialize Bluetooth A2DP Sink Profile, status: %d", status);
-                               return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       /* Register Audio sink module event handler */
-                       _bt_service_register_event_handler_callback(module, _bt_a2dp_sink_event_handler);
-                       break;
-               }
-               case BT_HFP_MODULE:
-               {
-                       return BLUETOOTH_ERROR_NOT_SUPPORT;
+       case BT_A2DP_SOURCE_MODULE: {
+               status = audio_enable(NULL, NULL);
+               if (OAL_STATUS_SUCCESS != status) {
+                       BT_ERR("Failed to initialize Bluetooth A2DP Source Profile, status: %d", status);
+                       return BLUETOOTH_ERROR_INTERNAL;
                }
-               case BT_AG_MODULE:
-               {
-                       status = hfp_enable(1);
-                       if (OAL_STATUS_SUCCESS != status) {
-                               BT_ERR("Failed to initialize Bluetooth HFP Audio Gateway Profile, status: %d", status);
-                               return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       /* Register Audio module event handler */
-                       _bt_service_register_event_handler_callback(module, _bt_hf_event_handler);
-                       break;
+               /* Register Audio module event handler */
+               _bt_service_register_event_handler_callback(module, _bt_a2dp_source_event_handler);
+               break;
+       }
+       case BT_A2DP_SINK_MODULE: {
+               status = a2dp_sink_enable(NULL, NULL);
+               if (status != OAL_STATUS_SUCCESS) {
+                       BT_ERR("Failed to initialize Bluetooth A2DP Sink Profile, status: %d", status);
+                       return BLUETOOTH_ERROR_INTERNAL;
                }
-               case BT_AUDIO_ALL_MODULE:
-               {
-                       /* Register Audio module event handler */
-                       _bt_service_register_event_handler_callback(module, __bt_audio_event_handler);
-                       break;
+               /* Register Audio sink module event handler */
+               _bt_service_register_event_handler_callback(module, _bt_a2dp_sink_event_handler);
+               break;
+       }
+       case BT_HFP_MODULE: {
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
+       }
+       case BT_AG_MODULE: {
+               status = hfp_enable(1);
+               if (OAL_STATUS_SUCCESS != status) {
+                       BT_ERR("Failed to initialize Bluetooth HFP Audio Gateway Profile, status: %d", status);
+                       return BLUETOOTH_ERROR_INTERNAL;
                }
-               case BT_AVRCP_CTRL_MODULE:
-               {
-                       status = avrcp_ct_enable();
-                       if (status != OAL_STATUS_SUCCESS) {
-                               BT_ERR( "Failed to initialize Bluetooth AVRCP Controller Profile, status: %d", status);
-                                       return BLUETOOTH_ERROR_INTERNAL;
-                       }
-                       /* Register Avrcp Controller event handler */
-                       _bt_service_register_event_handler_callback(module, _bt_avrcp_ctrl_event_handler);
-                       break;
+               /* Register Audio module event handler */
+               _bt_service_register_event_handler_callback(module, _bt_hf_event_handler);
+               break;
+       }
+       case BT_AUDIO_ALL_MODULE: {
+               /* Register Audio module event handler */
+               _bt_service_register_event_handler_callback(module, __bt_audio_event_handler);
+               break;
+       }
+       case BT_AVRCP_CTRL_MODULE: {
+               status = avrcp_ct_enable();
+               if (status != OAL_STATUS_SUCCESS) {
+                       BT_ERR( "Failed to initialize Bluetooth AVRCP Controller Profile, status: %d", status);
+                       return BLUETOOTH_ERROR_INTERNAL;
                }
-               default:
-                       BT_ERR("Not Supported: Module [%d]", module);
-                       return BLUETOOTH_ERROR_NOT_SUPPORT;
+               /* Register Avrcp Controller event handler */
+               _bt_service_register_event_handler_callback(module, _bt_avrcp_ctrl_event_handler);
+               break;
+       }
+       case BT_AVRCP_MODULE: {
+               /* Initialize AVRCP Target */
+               ret = _bt_service_avrcp_enable();
+               break;
+       }
+       default:
+               BT_ERR("Not Supported: Module [%d]", module);
+               return BLUETOOTH_ERROR_NOT_SUPPORT;
        }
 
        BT_INFO("Bluetooth audio interface initialised");
@@ -547,24 +555,21 @@ static void __bt_audio_event_handler(int oal_event, gpointer event_data)
        BT_INFO("+");
 
        switch(oal_event) {
-       case OAL_EVENT_DEVICE_PROPERTIES:
-       {
+       case OAL_EVENT_DEVICE_PROPERTIES: {
                BT_INFO("Device properties received");
                __bt_audio_device_property_event_handler((event_dev_properties_t*)event_data);
+               break;
        }
-       break;
-       case OAL_EVENT_ADAPTER_DISABLED:
-       {
+       case OAL_EVENT_ADAPTER_DISABLED: {
                BT_INFO("Adapter Disabled..cleanup resources");
                __bt_audio_cleanup_resources();
+               break;
        }
-       break;
-       case OAL_EVENT_ADAPTER_ENABLED:
-       {
+       case OAL_EVENT_ADAPTER_ENABLED: {
                /*TODO Currently not handled */
                BT_INFO("Adapter Enabled..");
+               break;
        }
-       break;
        default:
                BT_ERR("Unknown event..[%d]", oal_event);
        }
@@ -758,7 +763,7 @@ static int __bt_process_audio_connect_all(bt_pending_audio_conn_t *info)
                result = _bt_a2dp_connect_remote_source(&device_address);
        }
        if (result == BLUETOOTH_ERROR_NONE) {
-               _bt_headset_set_local_connection(TRUE);
+               //_bt_headset_set_local_connection(TRUE);
                /* Add data to the connected list */
                _bt_add_headset_to_list(type, BT_STATE_CONNECTING, info->address);
        } else {
@@ -973,20 +978,7 @@ int _bt_audio_disconnect(int type, bluetooth_device_address_t *device_address)
                return BLUETOOTH_ERROR_IN_PROGRESS;
        }
 
-       switch (type) {
-               case BT_AUDIO_HSP:  /* Remote is HFP HF unit */
-               case BT_AUDIO_A2DP: /* Remote is A2DP Sink */
-                       ret = __bt_process_audio_profile_disconnect(type, device_address);
-                       break;
-               case BT_AVRCP:
-               case BT_AUDIO_A2DP_SOURCE: /* Remote is A2DP Source */
-                       ret = __bt_process_audio_profile_disconnect(type, device_address);
-                       break;
-               default:
-                       BT_ERR("Unknown role");
-                       return BLUETOOTH_ERROR_INTERNAL;
-       }
-
+       ret = __bt_process_audio_profile_disconnect(type, device_address);
        return ret;
 }
 
@@ -1041,6 +1033,10 @@ void _bt_remove_headset_from_list(int type, const char *address)
                                if (connected_device->type & BT_AUDIO_ALL)
                                        connected_device->type &= ~(BT_AUDIO_ALL);
                                break;
+                       case BT_AVRCP_TARGET:
+                               if (connected_device->type & BT_AVRCP_TARGET)
+                                       connected_device->type &= ~(BT_AVRCP_TARGET);
+                               break;
                        case BT_AVRCP:
                                if (connected_device->type & BT_AVRCP)
                                        connected_device->type &= ~(BT_AVRCP);
index 7190527..e4c2d2e 100644 (file)
@@ -32,6 +32,7 @@
 #include "bt-service-core-adapter.h"
 #include "bt-service-core-device.h"
 #include "bt-service-audio-common.h"
+#include "bt-service-avrcp-tg.h"
 #include "bt-service-avrcp-ctrl.h"
 
 #ifdef TIZEN_DPM_ENABLE
@@ -41,6 +42,9 @@
 #include "bt-service-rfcomm.h"
 #include "bt-service-hdp.h"
 
+/* For AVRCP target role */
+static char *current_sender_playing = NULL;
+
 /* For maintaining Application Sync API call requests */
 GSList *invocation_list = NULL;
 
@@ -1252,6 +1256,44 @@ int __bt_bluez_request(int function_name,
                }
                break;
        }
+       case BT_AVRCP_TARGET_CONNECT: {
+               bluetooth_device_address_t address = { {0} };
+
+               __bt_service_get_parameters(in_param1,
+                       &address, sizeof(bluetooth_device_address_t));
+
+               result = _bt_audio_connect(BT_AVRCP_TARGET, &address);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       g_array_append_vals(*out_param1, &address,
+                       sizeof(bluetooth_device_address_t));
+               } else {
+                       char *addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+                       _bt_convert_addr_type_to_string(addr, address.addr);
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)addr);
+               }
+               break;
+       }
+       case BT_AVRCP_TARGET_DISCONNECT: {
+               bluetooth_device_address_t address = { {0} };
+
+               __bt_service_get_parameters(in_param1,
+                               &address, sizeof(bluetooth_device_address_t));
+
+               result = _bt_audio_disconnect(BT_AVRCP_TARGET, &address);
+               if (result != BLUETOOTH_ERROR_NONE) {
+                       g_array_append_vals(*out_param1, &address,
+                                       sizeof(bluetooth_device_address_t));
+               } else {
+                       char *addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+                       _bt_convert_addr_type_to_string(addr, address.addr);
+                       sender = (char*)g_dbus_method_invocation_get_sender(context);
+                       _bt_save_invocation_context(context, result, sender,
+                                       function_name, (gpointer)addr);
+               }
+               break;
+       }
         case BT_AVRCP_CONTROL_CONNECT: {
                 bluetooth_device_address_t address = { {0} };
 
@@ -1442,6 +1484,75 @@ int __bt_bluez_request(int function_name,
                result = BLUETOOTH_ERROR_NONE;
                break;
        }
+       case BT_AVRCP_SET_TRACK_INFO: {
+               media_metadata_t data;
+               media_metadata_attributes_t meta_data;
+
+               memset(&data, 0x00, sizeof(media_metadata_t));
+               memset(&meta_data, 0x00, sizeof(media_metadata_attributes_t));
+
+               __bt_service_get_parameters(in_param1,
+                               &data, sizeof(media_metadata_t));
+
+               meta_data.title = g_strdup(data.title);
+               meta_data.artist = g_strdup(data.artist);
+               meta_data.album = g_strdup(data.album);
+               meta_data.genre = g_strdup(data.genre);
+               meta_data.total_tracks = data.total_tracks;
+               meta_data.number = data.number;
+               meta_data.duration = (int64_t) data.duration;
+
+               result = _bt_avrcp_set_track_info(&meta_data);
+
+               g_free((gpointer)meta_data.title);
+               g_free((gpointer)meta_data.artist);
+               g_free((gpointer)meta_data.album);
+               g_free((gpointer)meta_data.genre);
+
+               break;
+       }
+       case BT_AVRCP_SET_PROPERTY: {
+               int type;
+               unsigned int value;
+               char *sender = NULL;
+               sender = (char *)g_dbus_method_invocation_get_sender(context);
+               BT_INFO("Sender %s", sender);
+
+               __bt_service_get_parameters(in_param1,
+                               &type, sizeof(int));
+               __bt_service_get_parameters(in_param2,
+                               &value, sizeof(unsigned int));
+
+               if (value == STATUS_PLAYING) {
+                       if (current_sender_playing)
+                               g_free(current_sender_playing);
+                       current_sender_playing = g_strdup(sender);
+               }
+
+               if (g_strcmp0(sender, current_sender_playing) == 0 ||
+                               current_sender_playing == NULL) {
+                       BT_INFO("Current Player Status %d type %d", value, type);
+               } else {
+                       BT_INFO("Current Player and this sender are different");
+                       result = BLUETOOTH_ERROR_NONE;
+                       break;
+               }
+
+               result = _bt_avrcp_set_property(type, value);
+
+               break;
+       }
+       case BT_AVRCP_SET_PROPERTIES: {
+               media_player_settings_t properties;
+
+               memset(&properties, 0x00, sizeof(media_player_settings_t));
+               __bt_service_get_parameters(in_param1,
+                               &properties, sizeof(media_player_settings_t));
+
+               result = _bt_avrcp_set_properties(&properties);
+
+               break;
+       }
        default:
                BT_INFO("UnSupported function [%d]", function_name);
                result = BLUETOOTH_ERROR_NOT_SUPPORT;
@@ -1618,6 +1729,8 @@ gboolean __bt_service_check_privilege(int function_name,
        case BT_AV_DISCONNECT:
        case BT_AV_SOURCE_CONNECT:
        case BT_AV_SOURCE_DISCONNECT:
+       case BT_AVRCP_TARGET_CONNECT:
+       case BT_AVRCP_TARGET_DISCONNECT:
        case BT_AVRCP_CONTROL_CONNECT:
        case BT_AVRCP_CONTROL_DISCONNECT:
        case BT_AVRCP_HANDLE_CONTROL:
index 08fc5b7..f11e16b 100644 (file)
@@ -43,6 +43,7 @@ _bt_service_event_handler_callback a2dp_sink_cb;
 _bt_service_event_handler_callback ag_cb;
 _bt_service_event_handler_callback hdp_cb;
 _bt_service_event_handler_callback avrcp_ctrl_cb;
+_bt_service_event_handler_callback avrcp_cb;
 
 void _bt_service_register_event_handler_callback(
                bt_service_module_t module, _bt_service_event_handler_callback cb)
@@ -84,6 +85,10 @@ void _bt_service_register_event_handler_callback(
                BT_INFO("Register BT_HEALTH_MODULE callback");
                hdp_cb = cb;
                break;
+       case BT_AVRCP_MODULE:
+               BT_INFO("Register BT_AVRCP_MODULE callback");
+               avrcp_cb = cb;
+               break;
        case BT_AVRCP_CTRL_MODULE:
                BT_INFO("Register BT_AVRCP_CTRL_MODULE callback");
                avrcp_ctrl_cb = cb;
@@ -120,6 +125,10 @@ void _bt_service_unregister_event_handler_callback(bt_service_module_t module)
                BT_INFO("Un-Register BT_HEALTH_MODULE callback");
                hdp_cb = NULL;
                break;
+       case BT_AVRCP_MODULE:
+               BT_INFO("Unregister BT_AVRCP_MODULE callback");
+               avrcp_cb = NULL;
+               break;
        case BT_AVRCP_CTRL_MODULE:
                BT_INFO("Un-Register BT_AVRCP_CTRL_MODULE callback");
                avrcp_ctrl_cb = NULL;
@@ -230,6 +239,17 @@ void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize l
                if (hdp_cb)
                        hdp_cb(event_type, event_data);
                break;
+       case OAL_EVENT_AVRCP_CONNECTED:
+       case OAL_EVENT_AVRCP_DISCONNECTED:
+       case OAL_EVENT_AVRCP_REMOTE_FEATURES:
+       case OAL_EVENT_AVRCP_SETTING_EQUALIZER_STATUS:
+       case OAL_EVENT_AVRCP_SETTING_REPEAT_STATUS:
+       case OAL_EVENT_AVRCP_SETTING_SHUFFLE_STATUS:
+       case OAL_EVENT_AVRCP_SETTING_SCAN_STATUS:
+       case OAL_EVENT_AVRCP_VOLUME_MUTE_CHANGED:
+               if (avrcp_cb)
+                       avrcp_cb(event_type, event_data);
+               break;
        case OAL_EVENT_AVRCP_CTRL_CONNECTING:
        case OAL_EVENT_AVRCP_CTRL_CONNECTED:
        case OAL_EVENT_AVRCP_CTRL_DISCONNECTING:
index 0c58d86..edeff56 100644 (file)
@@ -36,12 +36,13 @@ typedef enum {
 } bt_pending_request_t;
 
 typedef enum {
-        BT_AUDIO_HSP = 0x01,   /* HSP Connection */
-        BT_AUDIO_A2DP,         /* A2DP Source Connection, remote device is A2DP Sink */
-        BT_AUDIO_ALL,          /* HSP and A2DP Source Connection */
-        BT_AVRCP = 0x05,       /* AVRCP Connection */
-        BT_AUDIO_A2DP_SOURCE,  /* A2DP Sink Connection, remote device is A2DP Source */
-       BT_AUDIO_HFP_SOURCE     /* HSP and A2DP Sink Connection */
+       BT_AUDIO_HSP = 0x01,    /* HSP Connection */
+       BT_AUDIO_A2DP = 0x02,           /* A2DP Source Connection, remote device is A2DP Sink */
+       BT_AUDIO_ALL = 0x03,            /* HSP and A2DP Source Connection */
+       BT_AVRCP_TARGET = 0x04, /* AVRCP Target Connection to remote AVRCP controller */
+       BT_AVRCP = 0x08,        /* AVRCP ctrl Connection to remote AVRCP target */
+       BT_AUDIO_A2DP_SOURCE = 0x10,    /* A2DP Sink Connection, remote device is A2DP Source */
+       BT_AUDIO_HFP_SOURCE = 0x20      /* HSP and A2DP Sink Connection */
 } bt_audio_type_t;
 
 typedef enum {
diff --git a/bt-service-adaptation/services/include/bt-service-avrcp-tg.h b/bt-service-adaptation/services/include/bt-service-avrcp-tg.h
new file mode 100755 (executable)
index 0000000..e5e1ad6
--- /dev/null
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *             http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+
+#ifndef _BT_SERVICE_AVRCP_TG_H_
+#define _BT_SERVICE_AVRCP_TG_H_
+
+#include <glib.h>
+#include <sys/types.h>
+
+#include "bluetooth-api.h"
+#include "bluetooth-media-control.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if 0
+
+#define BT_MEDIA_OBJECT_PATH "/Musicplayer"
+
+#define BT_AVRCP_ERROR (__bt_avrcp_error_quark())
+
+#define BT_ERROR_INTERNAL "InternalError"
+#define BT_ERROR_INVALID_PARAM "InvalidParameters"
+#define BT_ERROR_INVALID_INTERFACE "InvalidInterface"
+
+typedef enum {
+       BT_AVRCP_ERROR_NONE,
+       BT_AVRCP_ERROR_INTERNAL,
+       BT_AVRCP_ERROR_INVALID_PARAM,
+       BT_AVRCP_ERROR_NOT_SUPPORTED,
+       BT_AVRCP_ERROR_INVALID_INTERFACE
+} bt_avrcp_error_t;
+
+int _bt_register_media_player(void);
+
+int _bt_unregister_media_player(void);
+#endif
+
+int _bt_avrcp_connect_remote_ctrl(bluetooth_device_address_t *address);
+
+int _bt_avrcp_disconnect_remote_ctrl(bluetooth_device_address_t *address);
+
+int _bt_avrcp_set_track_info(media_metadata_attributes_t *meta_data);
+
+int _bt_avrcp_set_properties(media_player_settings_t *properties);
+
+int _bt_avrcp_set_property(int type, unsigned int value);
+
+int _bt_service_avrcp_enable(void);
+int _bt_service_avrcp_disable(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_AVRCP_TG_H_*/
index 9e487c0..8906220 100644 (file)
@@ -41,7 +41,8 @@ typedef enum {
        BT_AG_MODULE,
        BT_HEALTH_MODULE,
        BT_AUDIO_ALL_MODULE,
-       BT_AVRCP_CTRL_MODULE
+       BT_AVRCP_MODULE,
+       BT_AVRCP_CTRL_MODULE,
 } bt_service_module_t;
 
 void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize len);