Add support for A2DP source and sink both role 48/301348/5
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:53:06 +0000 (09:53 +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 1e57986..b7c0400 100644 (file)
@@ -1655,11 +1655,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;
@@ -1670,7 +1666,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;
@@ -2687,37 +2683,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;
 
@@ -2842,14 +2818,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 2ce4f47..9f4ae11 100644 (file)
@@ -2967,37 +2967,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,
@@ -3019,9 +2990,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 5a53017..655833b 100644 (file)
@@ -68,8 +68,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 {
@@ -1529,16 +1527,16 @@ media_endpoint_create(struct media_adapter *adapter,
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        if (strcasecmp(uuid, A2DP_SOURCE_UUID) == 0) {
                source_endpoint = endpoint;
-               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SINK_ROLE)
-                       return endpoint;
-               else
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SOURCE_ROLE)
                        succeeded = endpoint_init_a2dp_source(endpoint, err);
+               else
+                       return endpoint;
        } else if (strcasecmp(uuid, A2DP_SINK_UUID) == 0) {
                sink_endpoint = endpoint;
-               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) == BLUETOOTH_A2DP_SOURCE_ROLE)
-                       return endpoint;
-               else
+               if (btd_adapter_get_a2dp_role(adapter->btd_adapter) & BLUETOOTH_A2DP_SINK_ROLE)
                        succeeded = endpoint_init_a2dp_sink(endpoint, err);
+               else
+                       return endpoint;
        } else if (strcasecmp(uuid, HFP_AG_UUID) == 0 ||
                                        strcasecmp(uuid, HSP_AG_UUID) == 0)
                succeeded = TRUE;
@@ -1692,7 +1690,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);
                }
@@ -1715,7 +1713,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);
                }
@@ -1758,15 +1756,7 @@ static DBusMessage *register_endpoint(DBusConnection *conn, DBusMessage *msg,
        uint8_t *capabilities = NULL;
        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 e4c0525..29ee93b 100644 (file)
@@ -677,7 +677,9 @@ 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
+       else if (adapter->a2dp_role == BLUETOOTH_A2DP_BOTH_ROLE)
+               g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "both");
+       else /* source */
                g_key_file_set_string(key_file, "General", "DefaultA2DPRole", "source");
 #endif
 
@@ -718,6 +720,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);
@@ -11838,9 +11845,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;
                }
@@ -11849,7 +11862,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);
        }
@@ -14354,14 +14369,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 70375c1..a7980f8 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 782cbdc..d85a0af 100755 (executable)
--- a/src/btd.h
+++ b/src/btd.h
@@ -118,7 +118,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 4ecfc0a..2dfc14e 100755 (executable)
@@ -88,7 +88,7 @@ static const char *supported_options[] = {
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        "EnableLEPrivacy",
        "PinCode",
-       "DefaultA2DPRoleSink",
+       "DefaultA2DPRole",
 #endif
        NULL
 };
@@ -903,13 +903,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);
@@ -1031,7 +1032,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)
@@ -1347,6 +1348,7 @@ int main(int argc, char *argv[])
                queue_destroy(btd_opts.kernel, free);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
        g_free(btd_opts.pin_code);
+       g_free(btd_opts.default_a2dp_role);
 #endif
 
        if (main_conf)
index 9666254..b1dd908 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 2a9c97c..0c8dc82 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 0feef89..3eee7eb 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: