Add support for A2DP source and sink both role 93/301493/1 accepted/tizen/7.0/unified/20231208.173552
authorWootak Jung <wootak.jung@samsung.com>
Wed, 15 Nov 2023 04:21:54 +0000 (13:21 +0900)
committerWootak Jung <wootak.jung@samsung.com>
Fri, 17 Nov 2023 00:55:29 +0000 (09:55 +0900)
- Change DefaultA2DPRoleSink to DefaultA2DPRole
- Enable both role in DA devices

Change-Id: I51c2a083f55e220d3430723e11d1af61de4fa4b7
Signed-off-by: Wootak Jung <wootak.jung@samsung.com>
profiles/audio/a2dp.c
profiles/audio/avdtp.c
profiles/audio/media.c
src/adapter.c
src/adapter.h
src/btd.h
src/main.c
src/main_da.conf
src/main_headless.conf
src/main_robot.conf

index 4cd4ddecee75699a63fac49aac597e665beb4d7d..ea3deb8b65eb5364db2723c797c84722b0e866e9 100644 (file)
@@ -1648,11 +1648,7 @@ 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;
@@ -1663,7 +1659,7 @@ static sdp_record_t *a2dp_record(uint8_t type)
        uint16_t lp = AVDTP_UUID;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        uint16_t a2dp_ver, avdtp_ver, feat;
-       if (sink_enabled) {
+       if (type == AVDTP_SEP_TYPE_SINK) {
                DBG("A2DP record for Sink role");
                a2dp_ver = 0x0102;
                avdtp_ver = 0x0103;
@@ -2656,37 +2652,17 @@ static bool a2dp_server_listen(struct a2dp_server *server)
 
        mode = btd_opts.avdtp.session_mode;
 
-#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_MODE, mode,
-                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-                               BT_IO_OPT_IMTU, 895,
-                               BT_IO_OPT_CENTRAL, 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_MODE, mode,
-                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-                               BT_IO_OPT_CENTRAL, 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_MODE, mode,
                                BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) /* for A2DP SINK connection */
+                               BT_IO_OPT_IMTU, 895,
+#endif
                                BT_IO_OPT_CENTRAL, true,
                                BT_IO_OPT_INVALID);
-#endif
        if (server->io)
                return true;
 
@@ -2813,14 +2789,7 @@ 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);
index 30e3d0b3f1b23c9661084117da3ab5f2ad9c0b27..9be8787097fb04d373d32346bdc5e646d8c2ae11 100644 (file)
@@ -2965,37 +2965,8 @@ static GIOChannel *l2cap_connect(struct avdtp *session, BtIOMode mode)
        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));
-#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_MODE, mode,
-                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-                               BT_IO_OPT_IMTU, 895,
-                               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_MODE, mode,
-                               BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-                               BT_IO_OPT_INVALID);
-       }
-#else
        if (session->phy)
                io = bt_io_connect(avdtp_connect_cb, session,
                                        NULL, &err,
@@ -3017,9 +2988,10 @@ static GIOChannel *l2cap_connect(struct avdtp *session, BtIOMode mode)
                                        BT_IO_OPT_PSM, AVDTP_PSM,
                                        BT_IO_OPT_MODE, mode,
                                        BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_MEDIUM,
-                                       BT_IO_OPT_INVALID);
+#if defined TIZEN_FEATURE_BLUEZ_MODIFY /* for A2DP SINK connection */
+                                       BT_IO_OPT_IMTU, 895,
 #endif
-
+                                       BT_IO_OPT_INVALID);
        if (!io) {
                error("%s", err->message);
                g_error_free(err);
index 91d73a0b9ec55ba4855a63a665064e69ec58b205..24fd771bb6cea06e4478a374fed6d4437d55a41d 100644 (file)
@@ -65,8 +65,6 @@
 #define SINK_SUSPEND_TIMEOUT 4         /* 4 seconds */
 
 unsigned int suspend_timer_id = 0;
-static gboolean a2dp_sink_support = false;
-static gboolean a2dp_source_support = true;
 #endif
 
 struct media_app {
@@ -1019,26 +1017,22 @@ static struct media_endpoint *media_endpoint_create(struct media_adapter *adapte
        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;
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SOURCE_ROLE)
+                       succeeded = endpoint_init_a2dp_source(endpoint, delay_reporting, err);
                else
-                       succeeded = endpoint_init_a2dp_source(endpoint,
-                                                       delay_reporting, err);
+                       return endpoint;
 #else
-               succeeded = endpoint_init_a2dp_source(endpoint,
-                                                       delay_reporting, err);
+               succeeded = endpoint_init_a2dp_source(endpoint, delay_reporting, err);
 #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;
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SINK_ROLE)
+                       succeeded = endpoint_init_a2dp_sink(endpoint, delay_reporting, err);
                else
-                       succeeded = endpoint_init_a2dp_sink(endpoint,
-                                                       delay_reporting, err);
+                       return endpoint;
 #else
-               succeeded = endpoint_init_a2dp_sink(endpoint,
-                                                       delay_reporting, err);
+               succeeded = endpoint_init_a2dp_sink(endpoint, delay_reporting, err);
 #endif
        } else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
                                        strcasecmp(uuid, HSP_AG_UUID) == 0)
@@ -1147,7 +1141,7 @@ static DBusMessage *a2dp_select_role(DBusConnection *conn, DBusMessage *msg,
                return btd_error_invalid_args(msg);
 
        if (!g_strcmp0(a2dp_role, A2DP_SINK_ROLE)) {
-               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SINK_ROLE) {
                        DBG("Already selected A2DP sink role");
                        return btd_error_already_exists(msg);
                }
@@ -1170,7 +1164,7 @@ static DBusMessage *a2dp_select_role(DBusConnection *conn, DBusMessage *msg,
 
                source_endpoint->sep = NULL;
        } else if (!g_strcmp0(a2dp_role, A2DP_SOURCE_ROLE)) {
-               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SOURCE_ROLE) {
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SOURCE_ROLE) {
                        DBG("Already selected A2DP source role");
                        return btd_error_already_exists(msg);
                }
@@ -1212,15 +1206,7 @@ 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);
index ae7d15d33857b71ed20c5fd4044248f77aab8e66..e05258359f62fa1af99bff6d8732af51e48068cd 100644 (file)
@@ -652,6 +652,8 @@ static void store_adapter_info(struct btd_adapter *adapter)
        /* Store A2DP Role */
        if (adapter->a2dp_role == BLUETOOTH_A2DP_SINK_ROLE)
                g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "sink");
+       else if (adapter->a2dp_role == BLUETOOTH_A2DP_BOTH_ROLE)
+               g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "both");
        else
                g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "source");
 #endif
@@ -694,6 +696,11 @@ void btd_adapter_set_a2dp_role(struct btd_adapter *adapter, bluetooth_a2dp_role_
        } else if (role == BLUETOOTH_A2DP_SINK_ROLE) {
                DBG("Set audio sink role");
                adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+       } else if (role == BLUETOOTH_A2DP_BOTH_ROLE) {
+               DBG("Set audio both role");
+               adapter->a2dp_role = BLUETOOTH_A2DP_BOTH_ROLE;
+#endif
        }
 
        store_adapter_info(adapter);
@@ -11688,9 +11695,15 @@ static void load_config(struct btd_adapter *adapter)
        /* Get A2DP Role */
        str = g_key_file_get_string(key_file, "General", "DefaultA2DPRole", &gerr);
        if (gerr || !str) {
-               if (btd_opts.default_a2dp_role_sink) {
-                       DBG("Default A2DP role is sink");
-                       adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
+               if (btd_opts.default_a2dp_role) {
+                       DBG("Default A2DP role is %s", btd_opts.default_a2dp_role);
+                       if (g_strcmp0(btd_opts.default_a2dp_role, "sink") == 0) {
+                               adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
+                       } else if (g_strcmp0(btd_opts.default_a2dp_role, "both") == 0) {
+                               adapter->a2dp_role = BLUETOOTH_A2DP_BOTH_ROLE;
+                       } else { /* source */
+                               adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
+                       }
                } else {
                        adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
                }
@@ -11699,7 +11712,9 @@ static void load_config(struct btd_adapter *adapter)
        } else {
                if (g_strcmp0(str, "sink") == 0)
                        adapter->a2dp_role = BLUETOOTH_A2DP_SINK_ROLE;
-               else if (g_strcmp0(str, "source") == 0)
+               else if (g_strcmp0(str, "both") == 0)
+                       adapter->a2dp_role = BLUETOOTH_A2DP_BOTH_ROLE;
+               else /* source */
                        adapter->a2dp_role = BLUETOOTH_A2DP_SOURCE_ROLE;
                g_free(str);
        }
@@ -14245,14 +14260,12 @@ static void new_link_key_callback(uint16_t index, uint16_t length,
                device_set_bonded(device, BDADDR_BREDR);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        } else {
-               if (btd_adapter_get_a2dp_role(adapter) == BLUETOOTH_A2DP_SINK_ROLE) {
+               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
-       }
 #endif
+       }
 
        bonding_complete(adapter, &addr->bdaddr, addr->type, 0);
 }
index 1bbe4c8e856b44f600f10245e03fdb7c800e4a6f..8b1d88883b523ba67cdb1a42e0afa8c50caccce9 100644 (file)
@@ -68,8 +68,9 @@ struct btd_device;
 struct queue;
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 typedef enum {
-       BLUETOOTH_A2DP_SOURCE_ROLE = 0,
+       BLUETOOTH_A2DP_SOURCE_ROLE = 1,
        BLUETOOTH_A2DP_SINK_ROLE,
+       BLUETOOTH_A2DP_BOTH_ROLE, /* SINK_ROLE | SOURCE_ROLE */
 } bluetooth_a2dp_role_t;
 #endif
 
index aae22989a53d150fd8a805b86343681918d4c621..674e47568a7acb65d29c9699f0156dac6581add0 100755 (executable)
--- a/src/btd.h
+++ b/src/btd.h
@@ -117,7 +117,7 @@ struct btd_opts {
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        gboolean        le_privacy;
        char            *pin_code;
-       gboolean        default_a2dp_role_sink;
+       char            *default_a2dp_role;
 #endif
 
        uint16_t        did_source;
index eee773be1f01acdee8c6a475bd6ebf58e740436b..215c277b7dc6f398b25d842f397e6a4a752828da 100755 (executable)
@@ -86,7 +86,7 @@ static const char *supported_options[] = {
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        "EnableLEPrivacy",
        "PinCode",
-       "DefaultA2DPRoleSink",
+       "DefaultA2DPRole",
 #endif
        NULL
 };
@@ -850,13 +850,14 @@ static void parse_config(GKeyFile *config)
                g_free(str);
        }
 
-       boolean = g_key_file_get_boolean(config, "General", "DefaultA2DPRoleSink", &err);
+       str = g_key_file_get_string(config, "General", "DefaultA2DPRole", &err);
        if (err) {
                DBG("%s", err->message);
                g_clear_error(&err);
        } else {
-               DBG("DefaultA2DPRoleSink=%s", boolean ? "true" : "false");
-               btd_opts.default_a2dp_role_sink = boolean;
+               DBG("DefaultA2DPRole=%s", str);
+               btd_opts.default_a2dp_role = g_strdup(str);
+               g_free(str);
        }
 #endif
        str = g_key_file_get_string(config, "GATT", "Cache", &err);
@@ -978,7 +979,7 @@ static void init_defaults(void)
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        btd_opts.le_privacy = FALSE;
        btd_opts.pin_code = NULL;
-       btd_opts.default_a2dp_role_sink = false;
+       btd_opts.default_a2dp_role = NULL;
 #endif
 
        if (sscanf(VERSION, "%hhu.%hhu", &major, &minor) != 2)
@@ -1297,6 +1298,7 @@ int main(int argc, char *argv[])
                queue_destroy(btd_opts.experimental, free);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        g_free(btd_opts.pin_code);
+       g_free(btd_opts.default_a2dp_role);
 #endif
 
        if (main_conf)
index 966625469514d2d3f25db38402ccc2b947f7b825..b1dd9084941c3c9e2bc616af301df23f0782ae85 100755 (executable)
@@ -76,11 +76,6 @@ FastConnectable = true
 EnableLEPrivacy = false
 #endif
 
-#ifdef TIZEN_APPLIANCE
-# Default A2DP role is sink in Fhub.
-DefaultA2DPRoleSink = true
-#endif
-
 # How long to keep temporary devices around
 # The value is in seconds. Default is 30.
 # 0 = disable timer, i.e. never keep temporary devices
@@ -90,6 +85,10 @@ TemporaryTimeout = 180
 #TemporaryTimeout = 30
 #endif
 
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+DefaultA2DPRole = both
+#endif
+
 #ifdef TIZEN_APPLIANCE
 [GATT]
 # GATT attribute cache.
index 2a9c97c07f240bb7a9721434ad479fda86a0f791..0c8dc82077e745d26ad1746b523ce9f9567ed83e 100644 (file)
@@ -83,7 +83,7 @@ Class = 0x40414 # Audio/Video(Loudspeaker)
 
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 # Default A2DP role is sink in headless device.
-DefaultA2DPRoleSink = true
+DefaultA2DPRole = sink
 #endif
 
 [GATT]
index 0feef892c19743380c50946a448e354e326bbc7b..3eee7ebeb7d31f9740ff8aaed15795ecb5f68c50 100644 (file)
@@ -77,11 +77,6 @@ Class = 0x040000 # Rendering, Miscellaneous
 #PinCode = 0000
 #endif
 
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
-# Default A2DP role is sink in headless device.
-DefaultA2DPRoleSink = false
-#endif
-
 [GATT]
 # GATT attribute cache.
 # Possible values: