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
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
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
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)
{
#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);
#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"
/* 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;
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);
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");
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;
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
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)
{
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;
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);
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,
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
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