A2DP profile multiple source support 77/195577/6
authorAvichal <avichal.a@samsung.com>
Fri, 14 Dec 2018 11:18:48 +0000 (16:48 +0530)
committerDoHyun Pyun <dh79.pyun@samsung.com>
Fri, 25 Jan 2019 03:04:55 +0000 (12:04 +0900)
there will be two sources source1 and source2
pause source 1 when source2 plays and viceversa

Change-Id: I2d424ce76278f505f9c270684248a76141e8e2b9
Signed-off-by: Avichal <avichal.a@samsung.com>
packaging/bluez.spec
profiles/audio/avctp.c
profiles/audio/avctp.h
profiles/audio/avdtp.c
profiles/audio/avdtp.h
profiles/audio/avrcp.c
profiles/audio/avrcp.h
profiles/audio/transport.c
profiles/audio/transport.h

index c7c7708..eee4059 100755 (executable)
@@ -169,7 +169,7 @@ autoreconf -fiv
 export CFLAGS_DEFAULT="$CFLAGS"
 
 export LDFLAGS=" -lncurses -Wl,--as-needed "
-export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
+export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
 
 %ifarch aarch64
 echo arch64
@@ -229,7 +229,7 @@ autoreconf -fiv
 export CFLAGS="$CFLAGS_DEFAULT"
 
 export LDFLAGS=" -lncurses -Wl,--as-needed "
-export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
+export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
 
 %ifarch aarch64
 echo arch64
@@ -291,7 +291,7 @@ autoreconf -fiv
 export CFLAGS="$CFLAGS_DEFAULT"
 
 export LDFLAGS=" -lncurses -Wl,--as-needed "
-export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
+export CFLAGS+=" -Werror -DTIZEN_FEATURE_BLUEZ_MODIFY -DTIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM -DTIZEN_FEATURE_BLUEZ_PBAP_SIM -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DTIZEN_FEATURE_BLUEZ_AVRCP_CONTROL -DTIZEN_FEATURE_BLUEZ_AVRCP_TARGET -DENABLE_AVRCP_CATEGORY1"
 
 %ifarch aarch64
 echo arch64
index 9585d28..cd7a69d 100644 (file)
@@ -1966,6 +1966,34 @@ int avctp_send_passthrough(struct avctp *session, uint8_t op)
 
        return avctp_passthrough_press(session, op);
 }
+
+#ifdef TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM
+static int avctp_passthrough_press_fast(struct avctp *session, uint8_t op)
+{
+       uint8_t operands[2];
+
+       DBG("%s", op2str(op));
+
+       /* Button pressed */
+       operands[0] = op & 0x7f;
+       operands[1] = 0;
+
+       return avctp_send_req(session, AVC_CTYPE_CONTROL,
+                               AVC_SUBUNIT_PANEL, AVC_OP_PASSTHROUGH,
+                               operands, sizeof(operands),
+                               NULL, NULL);
+}
+
+int avctp_send_passthrough_send_fast(struct avctp *session, uint8_t op)
+{
+       /* Auto release if key pressed */
+       if (session->key.timer > 0)
+               release_pressed(session);
+
+       return avctp_passthrough_press_fast(session, op);
+}
+#endif
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 int avctp_send_release_passthrough(struct avctp *session, uint8_t op)
 {
index ac5cdca..80fb9d1 100755 (executable)
@@ -181,6 +181,9 @@ int avctp_send_passthrough(struct avctp *session, uint8_t op);
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 int avctp_send_release_passthrough(struct avctp *session, uint8_t op);
 #endif
+#ifdef TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM
+int avctp_send_passthrough_send_fast(struct avctp *session, uint8_t op);
+#endif
 int avctp_send_vendordep(struct avctp *session, uint8_t transaction,
                                uint8_t code, uint8_t subunit,
                                uint8_t *operands, size_t operand_count);
index b52816d..c0251cb 100644 (file)
@@ -56,6 +56,9 @@
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 #include "src/service.h"
 #include "../../profile.h"
+#ifdef TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM
+#include "avrcp.h"
+#endif
 #endif
 
 #include "avdtp.h"
@@ -398,6 +401,13 @@ struct avdtp_stream {
 
 /* Structure describing an AVDTP connection between two devices */
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+struct avdtp_source_info {
+       struct btd_device *dev;
+       bool pause;
+};
+#endif
+
 struct avdtp {
        unsigned int ref;
 
@@ -438,6 +448,10 @@ struct avdtp {
 
 static GSList *state_callbacks = NULL;
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+static GSList *list_source = NULL;
+#endif
+
 static int send_request(struct avdtp *session, gboolean priority,
                        struct avdtp_stream *stream, uint8_t signal_id,
                        void *buffer, size_t size);
@@ -2050,15 +2064,89 @@ failed:
                                AVDTP_OPEN, &err, sizeof(err));
 }
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+void avdtp_set_source_status(struct btd_device *dev, bool pause)
+{
+       GSList *l = list_source;
+
+       while (l) {
+               struct avdtp_source_info *ldev = l->data;
+
+               if (ldev->dev != dev && pause == false && ldev->pause == false) {
+                       avrcp_pause(ldev->dev);
+                       DBG("sending pause from status");
+                       ldev->pause = true;
+               } else if (ldev->dev == dev) {
+                       ldev->pause = pause;
+               }
+
+               l = l->next;
+       }
+}
+
+static void avdtp_add_source_device(struct btd_device *dev)
+{
+       bool found = false;
+       GSList *l = list_source;
+
+       while (l) {
+               struct avdtp_source_info *ldev = l->data;
+
+               if (ldev->dev == dev) {
+                       DBG("in device %p device %p", ldev->dev, dev);
+                       ldev->pause = false;
+                       found = true;
+               } else {
+                       if (ldev->pause == false) {
+                               avrcp_pause(ldev->dev);
+                               DBG("Sending pause from steam");
+                               ldev->pause = true;
+                       }
+               }
+
+               l = l->next;
+       }
+
+       if (!found) {
+               struct avdtp_source_info *p;
+
+               p  = g_new0(struct avdtp_source_info, 1);
+               p->dev = dev;
+               p->pause = false;
+               list_source = g_slist_append(list_source, p);
+       }
+}
+
+static void avdtp_remove_source_devce(struct btd_device *dev)
+{
+       GSList *l;
+
+       for (l = list_source; l != NULL; l = l->next) {
+               struct avdtp_source_info *ldev = l->data;
+               if (ldev && ldev->dev == dev) {
+                       list_source = g_slist_remove(list_source, ldev);
+                       g_free(ldev);
+                       return;
+               }
+       }
+}
+#endif
+
 static gboolean avdtp_start_cmd(struct avdtp *session, uint8_t transaction,
                                struct start_req *req, unsigned int size)
 {
+
        struct avdtp_local_sep *sep;
        struct avdtp_stream *stream;
        struct stream_rej rej;
        struct seid *seid;
        uint8_t err, failed_seid;
-       int seid_count, i;
+       int seid_count;
+       int i;
+
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+       avdtp_add_source_device(session->device);
+#endif
 
        if (size < sizeof(struct start_req)) {
                error("Too short start request");
@@ -2117,6 +2205,10 @@ static gboolean avdtp_close_cmd(struct avdtp *session, uint8_t transaction,
        struct avdtp_stream *stream;
        uint8_t err;
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+       avdtp_remove_source_devce(session->device);
+#endif
+
        if (size < sizeof(struct seid_req)) {
                error("Too short close request");
                return FALSE;
index 8281a2b..acddd88 100755 (executable)
@@ -307,3 +307,7 @@ struct avdtp_server *avdtp_get_server(struct avdtp_local_sep *lsep);
 
 struct avdtp *avdtp_new(GIOChannel *chan, struct btd_device *device,
                                                        struct queue *lseps);
+
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+void avdtp_set_source_status(struct btd_device *dev, bool pause);
+#endif
index 295b3f0..0a32e13 100644 (file)
@@ -3183,6 +3183,26 @@ static int ct_press(struct avrcp_player *player, uint8_t op)
        return 0;
 }
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+static int ct_press_send_atonce(struct avrcp_player *player, uint8_t op)
+{
+       int err;
+       struct avrcp *session;
+
+       session = player->sessions->data;
+       if (session == NULL)
+               return -ENOTCONN;
+
+       set_ct_player(session, player);
+
+       err = avctp_send_passthrough_send_fast(session->conn, op);
+       if (err < 0)
+               return err;
+
+       return 0;
+}
+#endif
+
 #ifdef TIZEN_FEATURE_BLUEZ_MODIFY
 static int ct_release(struct avrcp_player *player, uint8_t op)
 {
@@ -3957,6 +3977,15 @@ static void avrcp_status_changed(struct avrcp *session,
        curval = media_player_get_status(mp);
        strval = status_to_string(value);
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+       DBG("AVRCP status changed to : %s", strval);
+
+       if (value == AVRCP_PLAY_STATUS_PAUSED)
+               media_transport_set_stream_status(session->dev, true);
+       else if ( value == AVRCP_PLAY_STATUS_PLAYING)
+               media_transport_set_stream_status(session->dev, false);
+#endif
+
        if (g_strcmp0(curval, strval) == 0)
                return;
 
@@ -4881,6 +4910,34 @@ int avrcp_set_volume(struct btd_device *dev, uint8_t volume, bool notify)
                                        avrcp_handle_set_volume, session);
 }
 
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+int avrcp_pause(struct btd_device *dev)
+{
+       struct avrcp_server *server;
+       struct avrcp *session;
+
+       DBG("AVRCP pause");
+
+       server = find_server(servers, device_get_adapter(dev));
+       if (server == NULL)
+               return -EINVAL;
+
+       session = find_session(server->sessions, dev);
+       if (session == NULL)
+               return -ENOTCONN;
+
+       if (session->controller) {
+               DBG("Calling controller pause");
+               ct_press_send_atonce(session->controller->player, AVC_PAUSE);
+       } else {
+               DBG("Controller not found");
+       }
+
+       return 0;
+}
+#endif
+
+
 static int avrcp_connect(struct btd_service *service)
 {
        struct btd_device *dev = btd_service_get_device(service);
index 86d310c..d5c749c 100755 (executable)
@@ -103,6 +103,11 @@ struct avrcp_player_cb {
        bool (*previous) (void *user_data);
 };
 
+
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+int avrcp_pause(struct btd_device *dev);
+#endif
+
 int avrcp_set_volume(struct btd_device *dev, uint8_t volume, bool notify);
 
 struct avrcp_player *avrcp_register_player(struct btd_adapter *adapter,
index 5cdcd5c..adb5fc6 100755 (executable)
@@ -1051,3 +1051,10 @@ void media_transport_update_device_volume(struct btd_device *dev,
                        media_transport_update_volume(transport, volume);
        }
 }
+
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+void media_transport_set_stream_status(struct btd_device *device, bool pause)
+{
+       avdtp_set_source_status(device, pause);
+}
+#endif
index 505ad5c..d529550 100755 (executable)
@@ -42,3 +42,7 @@ void transport_get_properties(struct media_transport *transport,
 uint8_t media_transport_get_device_volume(struct btd_device *dev);
 void media_transport_update_device_volume(struct btd_device *dev,
                                                                uint8_t volume);
+
+#if defined(TIZEN_FEATURE_BLUEZ_MODIFY) && defined(TIZEN_FEATURE_BLUEZ_A2DP_MULTISTREAM)
+void media_transport_set_stream_status(struct btd_device *device, bool pause);
+#endif