Add the A2DP runtime role change API 27/117127/2
authorLee Hyuk <hyuk0512.lee@samsung.com>
Fri, 3 Mar 2017 02:14:23 +0000 (11:14 +0900)
committerLee Hyuk <hyuk0512.lee@samsung.com>
Fri, 3 Mar 2017 04:06:06 +0000 (13:06 +0900)
Change-Id: Iae6501fa86ef18e2bb69c0f9b54ab26084d8d46f
Signed-off-by: Lee Hyuk <hyuk0512.lee@samsung.com>
profiles/audio/a2dp.c
profiles/audio/avdtp.c
profiles/audio/media.c
src/adapter.c
src/adapter.h

index 78c4dc2..e462468 100644 (file)
@@ -1219,7 +1219,11 @@ static struct avdtp_sep_ind endpoint_ind = {
        .delayreport            = endpoint_delayreport_ind,
 };
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static sdp_record_t *a2dp_record(uint8_t type, gboolean sink_enabled)
+#else
 static sdp_record_t *a2dp_record(uint8_t type)
+#endif
 {
        sdp_list_t *svclass_id, *pfseq, *apseq, *root;
        uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
@@ -1229,11 +1233,18 @@ static sdp_record_t *a2dp_record(uint8_t type)
        sdp_data_t *psm, *version, *features;
        uint16_t lp = AVDTP_UUID;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-#ifdef SUPPORT_LOCAL_DEVICE_A2DP_SINK
-       uint16_t a2dp_ver = 0x0102, avdtp_ver = 0x0103, feat = 0x0002;
-#else
-       uint16_t a2dp_ver = 0x0102, avdtp_ver = 0x0103, feat = 0x0001;
-#endif
+       uint16_t a2dp_ver, avdtp_ver, feat;
+       if (sink_enabled) {
+               DBG("A2DP record for Sink role");
+               a2dp_ver = 0x0102;
+               avdtp_ver = 0x0103;
+               feat = 0x0002;
+       } else {
+               DBG("A2DP record for Source role");
+               a2dp_ver = 0x0102;
+               avdtp_ver = 0x0103;
+               feat = 0x0001;
+       }
 #else
        uint16_t a2dp_ver = 0x0103, avdtp_ver = 0x0103, feat = 0x000f;
 #endif
@@ -1603,16 +1614,34 @@ static bool a2dp_server_listen(struct a2dp_server *server)
        if (server->io)
                return true;
 
-       server->io = bt_io_listen(NULL, confirm_cb, server, NULL, &err,
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY)
+       if (btd_adapter_get_a2dp_role(server->adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+               server->io = bt_io_listen(NULL, confirm_cb, server, NULL, &err,
                                BT_IO_OPT_SOURCE_BDADDR,
                                btd_adapter_get_address(server->adapter),
                                BT_IO_OPT_PSM, AVDTP_PSM,
                                BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(SUPPORT_LOCAL_DEVICE_A2DP_SINK)
                                BT_IO_OPT_IMTU, 895,
-#endif
                                BT_IO_OPT_MASTER, true,
                                BT_IO_OPT_INVALID);
+       } else {
+               server->io = bt_io_listen(NULL, confirm_cb, server, NULL, &err,
+                               BT_IO_OPT_SOURCE_BDADDR,
+                               btd_adapter_get_address(server->adapter),
+                               BT_IO_OPT_PSM, AVDTP_PSM,
+                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+                               BT_IO_OPT_MASTER, true,
+                               BT_IO_OPT_INVALID);
+       }
+#else
+       server->io = bt_io_listen(NULL, confirm_cb, server, NULL, &err,
+                       BT_IO_OPT_SOURCE_BDADDR,
+                       btd_adapter_get_address(server->adapter),
+                       BT_IO_OPT_PSM, AVDTP_PSM,
+                       BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+                       BT_IO_OPT_MASTER, true,
+                       BT_IO_OPT_INVALID);
+#endif
        if (server->io)
                return true;
 
@@ -1739,7 +1768,14 @@ struct a2dp_sep *a2dp_add_sep(struct btd_adapter *adapter, uint8_t type,
        if (*record_id != 0)
                goto add;
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE)
+               record = a2dp_record(type, true);
+       else
+               record = a2dp_record(type, false);
+#else
        record = a2dp_record(type);
+#endif
        if (!record) {
                error("Unable to allocate new service record");
                a2dp_unregister_sep(sep);
@@ -2563,9 +2599,7 @@ static struct btd_adapter_driver media_driver = {
 static int a2dp_init(void)
 {
        btd_register_adapter_driver(&media_driver);
-#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(SUPPORT_LOCAL_DEVICE_A2DP_SINK)
        btd_profile_register(&a2dp_source_profile);
-#endif
        btd_profile_register(&a2dp_sink_profile);
 
        return 0;
index ed06f01..b689416 100644 (file)
@@ -1434,19 +1434,14 @@ static gboolean disconnect_timeout(gpointer user_data)
        return FALSE;
 }
 
-#if defined TIZEN_FEATURE_BLUEZ_MODIFY && defined SUPPORT_LOCAL_DEVICE_A2DP_SINK
-static void set_disconnect_timer(struct avdtp *session, gboolean disconn)
-#else
-static void set_disconnect_timer(struct avdtp *session)
-#endif
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+static void set_disconnect_timer_for_sink(struct avdtp *session, gboolean disconn)
 {
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        char name[6];
-#endif
+
        if (session->dc_timer)
                remove_disconnect_timer(session);
 
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        device_get_name(session->device, name, sizeof(name));
        DBG("name : [%s]", name);
        if (g_str_equal(name, "VW BT") || g_str_equal(name, "VW MI") ||
@@ -1457,8 +1452,6 @@ static void set_disconnect_timer(struct avdtp *session)
                session->dc_timer = g_timeout_add(200, disconnect_timeout,
                                session);
        } else {
-#endif
-#if defined TIZEN_FEATURE_BLUEZ_MODIFY && defined SUPPORT_LOCAL_DEVICE_A2DP_SINK
                if (disconn == TRUE)
                        session->dc_timer = g_timeout_add(100,
                                        disconnect_timeout,
@@ -1467,12 +1460,34 @@ static void set_disconnect_timer(struct avdtp *session)
                        session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
                                        disconnect_timeout,
                                        session);
-#else
+       }
+}
+#endif
+
+static void set_disconnect_timer(struct avdtp *session)
+{
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       char name[6];
+#endif
+       if (session->dc_timer)
+               remove_disconnect_timer(session);
+
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       device_get_name(session->device, name, sizeof(name));
+       DBG("name : [%s]", name);
+       if (g_str_equal(name, "VW BT") || g_str_equal(name, "VW MI") ||
+                                               g_str_equal(name, "Seat ")) {
+               session->dc_timer = g_timeout_add_seconds(3, disconnect_timeout,
+                               session);
+       } else if (g_str_equal(name, "CAR M")) {
+               session->dc_timer = g_timeout_add(200, disconnect_timeout,
+                               session);
+       } else {
                session->dc_timer = g_timeout_add_seconds(DISCONNECT_TIMEOUT,
                                disconnect_timeout,
                                session);
-#endif
        }
+#endif
 }
 
 void avdtp_unref(struct avdtp *session)
@@ -1481,14 +1496,21 @@ void avdtp_unref(struct avdtp *session)
                return;
 
        session->ref--;
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+       struct btd_adapter *adapter;
+       adapter = avdtp_get_adapter(session);
+#endif
 
        DBG("%p: ref=%d", session, session->ref);
 
        if (session->ref > 0)
                return;
 
-#if defined TIZEN_FEATURE_BLUEZ_MODIFY && defined SUPPORT_LOCAL_DEVICE_A2DP_SINK
-       set_disconnect_timer(session, TRUE);
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+       if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE)
+               set_disconnect_timer_for_sink(session, TRUE);
+       else
+               set_disconnect_timer(session);
 #else
        set_disconnect_timer(session);
 #endif
@@ -2598,6 +2620,10 @@ static void avdtp_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
        struct avdtp *session = user_data;
        char address[18];
        int err_no = EIO;
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+       struct btd_adapter *adapter;
+       adapter = avdtp_get_adapter(session);
+#endif
 
        if (err) {
                err_no = err->code;
@@ -2646,12 +2672,16 @@ static void avdtp_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)
                                                (GIOFunc) session_cb, session,
                                                NULL);
 
-               if (session->stream_setup)
-#if defined TIZEN_FEATURE_BLUEZ_MODIFY && defined SUPPORT_LOCAL_DEVICE_A2DP_SINK
-                       set_disconnect_timer(session, FALSE);
+               if (session->stream_setup) {
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+                       if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE)
+                               set_disconnect_timer_for_sink(session, FALSE);
+                       else
+                               set_disconnect_timer(session);
 #else
                        set_disconnect_timer(session);
 #endif
+               }
        } else if (session->pending_open)
                handle_transport_connect(session, chan, session->imtu,
                                                                session->omtu);
@@ -2715,20 +2745,45 @@ static GIOChannel *l2cap_connect(struct avdtp *session)
        GError *err = NULL;
        GIOChannel *io;
        const bdaddr_t *src;
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+       struct btd_adapter *adapter;
+       adapter = avdtp_get_adapter(session);
+#endif
 
        src = btd_adapter_get_address(device_get_adapter(session->device));
 
-       io = bt_io_connect(avdtp_connect_cb, session,
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY
+       if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+               io = bt_io_connect(avdtp_connect_cb, session,
                                NULL, &err,
                                BT_IO_OPT_SOURCE_BDADDR, src,
                                BT_IO_OPT_DEST_BDADDR,
                                device_get_address(session->device),
                                BT_IO_OPT_PSM, AVDTP_PSM,
                                BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-#if defined TIZEN_FEATURE_BLUEZ_MODIFY && defined SUPPORT_LOCAL_DEVICE_A2DP_SINK
                                BT_IO_OPT_IMTU, 895,
-#endif
                                BT_IO_OPT_INVALID);
+       } else {
+               io = bt_io_connect(avdtp_connect_cb, session,
+                               NULL, &err,
+                               BT_IO_OPT_SOURCE_BDADDR, src,
+                               BT_IO_OPT_DEST_BDADDR,
+                               device_get_address(session->device),
+                               BT_IO_OPT_PSM, AVDTP_PSM,
+                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+                               BT_IO_OPT_INVALID);
+       }
+#else
+       io = bt_io_connect(avdtp_connect_cb, session,
+                       NULL, &err,
+                       BT_IO_OPT_SOURCE_BDADDR, src,
+                       BT_IO_OPT_DEST_BDADDR,
+                       device_get_address(session->device),
+                       BT_IO_OPT_PSM, AVDTP_PSM,
+                       BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+                       BT_IO_OPT_INVALID);
+#endif
+
        if (!io) {
                error("%s", err->message);
                g_error_free(err);
index 33ed69b..c1ada49 100644 (file)
 #define MEDIA_ENDPOINT_INTERFACE "org.bluez.MediaEndpoint1"
 #define MEDIA_PLAYER_INTERFACE "org.mpris.MediaPlayer2.Player"
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+#define A2DP_SINK_ROLE "sink"
+#define A2DP_SOURCE_ROLE "source"
+#endif
+
 #define REQUEST_TIMEOUT (3 * 1000)             /* 3 seconds */
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
@@ -140,6 +145,10 @@ static GSList *adapters = NULL;
 static gboolean set_avrcp_status = FALSE;
 static gboolean send_track_changed_event = FALSE;
 
+gboolean current_delay_reporting = false;
+struct media_endpoint *source_endpoint = NULL;
+struct media_endpoint *sink_endpoint = NULL;
+
 static int media_set_sink_callback(struct btd_device *device,
                                struct media_player *mp);
 static void media_sink_state_changed_cb(struct btd_service *service,
@@ -234,7 +243,9 @@ static void media_endpoint_remove(struct media_endpoint *endpoint)
 
        if (endpoint->sep) {
                a2dp_remove_sep(endpoint->sep);
+#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
                return;
+#endif
        }
 
        info("Endpoint unregistered: sender=%s path=%s", endpoint->sender,
@@ -791,7 +802,11 @@ static gboolean endpoint_init_a2dp_source(struct media_endpoint *endpoint,
        endpoint->sep = a2dp_add_sep(endpoint->adapter->btd_adapter,
                                        AVDTP_SEP_TYPE_SOURCE, endpoint->codec,
                                        delay_reporting, &a2dp_endpoint,
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+                                       endpoint, NULL, err);
+#else
                                        endpoint, a2dp_destroy_endpoint, err);
+#endif
        if (endpoint->sep == NULL)
                return FALSE;
 
@@ -805,7 +820,11 @@ static gboolean endpoint_init_a2dp_sink(struct media_endpoint *endpoint,
        endpoint->sep = a2dp_add_sep(endpoint->adapter->btd_adapter,
                                        AVDTP_SEP_TYPE_SINK, endpoint->codec,
                                        delay_reporting, &a2dp_endpoint,
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+                                       endpoint, NULL, err);
+#else
                                        endpoint, a2dp_destroy_endpoint, err);
+#endif
        if (endpoint->sep == NULL)
                return FALSE;
 
@@ -935,13 +954,31 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
 
        endpoint->adapter = adapter;
 
-       if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0)
+       if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+               source_endpoint = endpoint;
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SINK_ROLE)
+                       return endpoint;
+               else
+                       succeeded = endpoint_init_a2dp_source(endpoint,
+                                                       delay_reporting, err);
+#else
                succeeded = endpoint_init_a2dp_source(endpoint,
                                                        delay_reporting, err);
-       else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0)
+#endif
+       } else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+               sink_endpoint = endpoint;
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SOURCE_ROLE)
+                       return endpoint;
+               else
+                       succeeded = endpoint_init_a2dp_sink(endpoint,
+                                                       delay_reporting, err);
+#else
                succeeded = endpoint_init_a2dp_sink(endpoint,
                                                        delay_reporting, err);
-       else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
+#endif
+       } else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
                                        strcasecmp(uuid, HSP_AG_UUID) == 0)
                succeeded = TRUE;
        else if (strcasecmp(uuid, HFP_HS_UUID) == 0 ||
@@ -978,6 +1015,36 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
        return endpoint;
 }
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static int parse_a2dp_uuid(DBusMessageIter *props, const char **uuid)
+{
+       gboolean has_uuid = FALSE;
+
+       while (dbus_message_iter_get_arg_type(props) == DBUS_TYPE_DICT_ENTRY) {
+               const char *key;
+               DBusMessageIter value, entry;
+               int var;
+
+               dbus_message_iter_recurse(props, &entry);
+               dbus_message_iter_get_basic(&entry, &key);
+
+               dbus_message_iter_next(&entry);
+               dbus_message_iter_recurse(&entry, &value);
+
+               var = dbus_message_iter_get_arg_type(&value);
+               if (strcasecmp(key, "UUID") == 0) {
+                       if (var != DBUS_TYPE_STRING)
+                               return -EINVAL;
+                       dbus_message_iter_get_basic(&value, uuid);
+                       has_uuid = TRUE;
+               }
+               dbus_message_iter_next(props);
+       }
+
+       return has_uuid ? 0 : -EINVAL;
+}
+#endif
+
 static int parse_properties(DBusMessageIter *props, const char **uuid,
                                gboolean *delay_reporting, uint8_t *codec,
                                uint8_t **capabilities, int *size)
@@ -1028,6 +1095,42 @@ static int parse_properties(DBusMessageIter *props, const char **uuid,
        return (has_uuid && has_codec) ? 0 : -EINVAL;
 }
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static DBusMessage *a2dp_select_role(DBusConnection *conn, DBusMessage *msg,
+                                       void *data)
+{
+       struct media_adapter *adapter = data;
+       DBusMessageIter args, props;
+       const char *a2dp_role;
+       gboolean ret;
+       int err;
+
+       if (!dbus_message_get_args(msg, NULL,
+                               DBUS_TYPE_STRING, &a2dp_role,
+                               DBUS_TYPE_INVALID))
+               return btd_error_invalid_args(msg);
+
+       if (!g_strcmp0(a2dp_role, A2DP_SINK_ROLE)) {
+               btd_adapter_set_a2dp_role(adapter->btd_adapter, BLUETOOTH_A2DP_SINK_ROLE);
+               a2dp_remove_sep(source_endpoint->sep);
+               ret = endpoint_init_a2dp_sink(sink_endpoint, current_delay_reporting, NULL);
+               if (!ret)
+                       DBG("could not init a2dp sink");
+       } else if (!g_strcmp0(a2dp_role, A2DP_SOURCE_ROLE)) {
+               btd_adapter_set_a2dp_role(adapter->btd_adapter, BLUETOOTH_A2DP_SOURCE_ROLE);
+               a2dp_remove_sep(sink_endpoint->sep);
+               ret = endpoint_init_a2dp_source(source_endpoint, current_delay_reporting, NULL);
+               if (!ret)
+                       DBG("could not init a2dp source");
+       } else {
+               DBG("invalid a2dp role");
+               return btd_error_invalid_args(msg);
+       }
+
+       return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
+}
+#endif
+
 static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
                                        void *data)
 {
@@ -1039,7 +1142,15 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
        uint8_t *capabilities;
        int size = 0;
        int err;
-
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+               a2dp_sink_support = true;
+               a2dp_source_support = false;
+       } else {
+               a2dp_sink_support = false;
+               a2dp_source_support = true;
+       }
+#endif
        sender = dbus_message_get_sender(msg);
 
        dbus_message_iter_init(msg, &args);
@@ -1058,15 +1169,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
                                                &capabilities, &size) < 0)
                return btd_error_invalid_args(msg);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-       if(!a2dp_sink_support && !g_strcmp0(uuid, A2DP_SINK_UUID)) {
-               error("A2DP sink role is not supported.");
-               return btd_error_not_supported(msg);
-       }
-
-       if(!a2dp_source_support && !g_strcmp0(uuid, A2DP_SOURCE_UUID)) {
-               error("A2DP source role is not supported.");
-               return btd_error_not_supported(msg);
-       }
+       current_delay_reporting = delay_reporting;
 #endif
        if (media_endpoint_create(adapter, sender, path, uuid, delay_reporting,
                                codec, capabilities, size, &err) == NULL) {
@@ -2162,6 +2265,10 @@ static const GDBusMethodTable media_methods[] = {
                NULL, register_player) },
        { GDBUS_METHOD("UnregisterPlayer",
                GDBUS_ARGS({ "player", "o" }), NULL, unregister_player) },
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       { GDBUS_METHOD("SelectRole",
+               GDBUS_ARGS({ "role", "s" }), NULL, a2dp_select_role) },
+#endif
        { },
 };
 
index ae4d2f8..b2c88ca 100644 (file)
@@ -322,6 +322,7 @@ struct btd_adapter {
        unsigned int db_id;             /* Service event handler for GATT db */
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        uint8_t central_rpa_res_support;
+       bluetooth_a2dp_role_t a2dp_role;
 #ifdef TIZEN_FEATURE_PLATFROM_SCAN_FILTER
        bool scan_filter_support;               /* platform's scan filtering support */
        uint8_t scan_type;              /* scan type */
@@ -537,6 +538,13 @@ static void store_adapter_info(struct btd_adapter *adapter)
        if (adapter->stored_alias)
                g_key_file_set_string(key_file, "General", "Alias",
                                                        adapter->stored_alias);
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       /* Store A2DP Role */
+       if (adapter->a2dp_role == BLUETOOTH_A2DP_SINK_ROLE)
+               g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "sink");
+       else
+               g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "source");
+#endif
        ba2str(&adapter->bdaddr, address);
        snprintf(filename, PATH_MAX, STORAGEDIR "/%s/settings", address);
 
@@ -549,6 +557,34 @@ static void store_adapter_info(struct btd_adapter *adapter)
        g_key_file_free(key_file);
 }
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+bluetooth_a2dp_role_t btd_adapter_get_a2dp_role(struct btd_adapter *adapter)
+{
+       if (!adapter)
+               return BLUETOOTH_A2DP_SOURCE_ROLE;
+
+       return adapter->a2dp_role;
+}
+
+void btd_adapter_set_a2dp_role(struct btd_adapter *adapter, bluetooth_a2dp_role_t role)
+{
+       if (!adapter) {
+               DBG("Could not set a2dp role");
+               return;
+       }
+
+       if (role == BLUETOOTH_A2DP_SOURCE_ROLE) {
+               DBG("Set audio source role");
+               adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
+       } else if (role == BLUETOOTH_A2DP_SINK_ROLE) {
+               DBG("Set audio sink role");
+               adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
+       }
+
+       store_adapter_info(adapter);
+}
+#endif
+
 static void trigger_pairable_timeout(struct btd_adapter *adapter);
 static void adapter_start(struct btd_adapter *adapter);
 static void adapter_stop(struct btd_adapter *adapter);
@@ -9336,7 +9372,9 @@ static void load_config(struct btd_adapter *adapter)
        char address[18];
        struct stat st;
        GError *gerr = NULL;
-
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       char *str;
+#endif
        ba2str(&adapter->bdaddr, address);
 
        key_file = g_key_file_new();
@@ -9386,6 +9424,21 @@ static void load_config(struct btd_adapter *adapter)
                gerr = NULL;
        }
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       /* Get A2DP Role */
+       str = g_key_file_get_string(key_file, "General", "DefaultA2DPRole", &gerr);
+       if (gerr || !str) {
+               adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
+               g_error_free(gerr);
+               gerr = NULL;
+       } else {
+               if (g_strcmp0(str, "sink") == 0)
+                       adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
+               else if (g_strcmp0(str, "source") == 0)
+                       adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
+       }
+#endif
+
        g_key_file_free(key_file);
 }
 
@@ -11682,10 +11735,12 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
                                                                key->pin_len);
 
                device_set_bonded(device, BDADDR_BREDR);
-#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(SUPPORT_LOCAL_DEVICE_A2DP_SINK)
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        } else {
-               DBG("store_hint %d", ev->store_hint);
-               btd_device_set_temporary(device, false);
+               if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+                       DBG("store_hint %d", ev->store_hint);
+                       btd_device_set_temporary(device, false);
+               }
        }
 #else
        }
index 46d80ae..985e28e 100644 (file)
@@ -69,8 +69,19 @@ typedef enum {
 struct btd_adapter;
 struct btd_device;
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+typedef enum {
+       BLUETOOTH_A2DP_SOURCE_ROLE = 0,
+       BLUETOOTH_A2DP_SINK_ROLE,
+} bluetooth_a2dp_role_t;
+#endif
+
 struct btd_adapter *btd_adapter_get_default(void);
 bool btd_adapter_is_default(struct btd_adapter *adapter);
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+bluetooth_a2dp_role_t btd_adapter_get_a2dp_role(struct btd_adapter *adapter);
+void btd_adapter_set_a2dp_role(struct btd_adapter *adapter, bluetooth_a2dp_role_t role);
+#endif
 uint16_t btd_adapter_get_index(struct btd_adapter *adapter);
 
 typedef void (*adapter_cb) (struct btd_adapter *adapter, gpointer user_data);