Linux bluetooth development
 help / color / mirror / Atom feed
From: Szymon Janc <szymon.janc@tieto.com>
To: linux-bluetooth@vger.kernel.org
Cc: Szymon Janc <szymon.janc@tieto.com>
Subject: [PATCH 6/6] android/avdtptest: Add support for receiving media as SINK
Date: Fri, 29 Aug 2014 15:17:58 +0200	[thread overview]
Message-ID: <1409318278-798-6-git-send-email-szymon.janc@tieto.com> (raw)
In-Reply-To: <1409318278-798-1-git-send-email-szymon.janc@tieto.com>

---
 android/avdtptest.c | 148 +++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 140 insertions(+), 8 deletions(-)

diff --git a/android/avdtptest.c b/android/avdtptest.c
index e4bb2d1..3cb9412 100644
--- a/android/avdtptest.c
+++ b/android/avdtptest.c
@@ -30,6 +30,7 @@
 #include <getopt.h>
 #include <unistd.h>
 #include <stdbool.h>
+#include <errno.h>
 
 #include <bluetooth/bluetooth.h>
 #include <bluetooth/hci.h>
@@ -37,6 +38,7 @@
 
 #include <glib.h>
 
+#include "src/shared/util.h"
 #include "btio/btio.h"
 #include "avdtp.h"
 
@@ -53,6 +55,7 @@ static bdaddr_t src;
 static bdaddr_t dst;
 
 static guint media_player = 0;
+static guint media_recorder = 0;
 static guint idle_id = 0;
 
 static bool fragment = false;
@@ -125,6 +128,107 @@ static void stop_media_player(void)
 	media_player = 0;
 }
 
+#if __BYTE_ORDER == __LITTLE_ENDIAN
+
+struct rtp_header {
+	unsigned cc:4;
+	unsigned x:1;
+	unsigned p:1;
+	unsigned v:2;
+
+	unsigned pt:7;
+	unsigned m:1;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+#elif __BYTE_ORDER == __BIG_ENDIAN
+
+struct rtp_header {
+	unsigned v:2;
+	unsigned p:1;
+	unsigned x:1;
+	unsigned cc:4;
+
+	unsigned m:1;
+	unsigned pt:7;
+
+	uint16_t sequence_number;
+	uint32_t timestamp;
+	uint32_t ssrc;
+	uint32_t csrc[0];
+} __attribute__ ((packed));
+
+#else
+#error "Unknown byte order"
+#endif
+
+static gboolean media_reader(GIOChannel *source, GIOCondition condition,
+								gpointer data)
+{
+	char buf[UINT16_MAX];
+	struct rtp_header *rtp = (void *) buf;
+	static bool decode = false;
+	uint16_t imtu;
+	int fd;
+
+	if (!avdtp_stream_get_transport(avdtp_stream, &fd, &imtu, NULL, NULL))
+		return TRUE;
+
+	if (read(fd, buf, imtu) < 0) {
+		printf("Reading failed (%s)\n", strerror(errno));
+		return TRUE;
+	}
+
+	if (!decode) {
+		printf("V=%u P=%u X=%u CC=%u M=%u PT=%u SeqNr=%d\n",
+			rtp->v, rtp->p, rtp->x, rtp->cc, rtp->m, rtp->pt,
+			be16_to_cpu(rtp->sequence_number));
+		decode = true;
+	}
+
+	return TRUE;
+}
+
+static bool start_media_recorder(void)
+{
+	int fd;
+	uint16_t omtu;
+	GIOChannel *chan;
+
+	printf("Media recording started\n");
+
+	if (media_recorder || !avdtp_stream)
+		return false;
+
+	if (!avdtp_stream_get_transport(avdtp_stream, &fd, NULL, &omtu, NULL))
+		return false;
+
+	chan = g_io_channel_unix_new(fd);
+
+	media_recorder = g_io_add_watch(chan, G_IO_IN, media_reader, NULL);
+	g_io_channel_unref(chan);
+
+	if (!media_recorder)
+		return false;
+
+	return true;
+}
+
+static void stop_media_recorder(void)
+{
+	if (!media_recorder)
+		return;
+
+	printf("Media recording stopped\n");
+
+	g_source_remove(media_recorder);
+	media_recorder = 0;
+}
+
 static void set_configuration_cfm(struct avdtp *session,
 					struct avdtp_local_sep *lsep,
 					struct avdtp_stream *stream,
@@ -308,7 +412,10 @@ static void start_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
 {
 	printf("%s\n", __func__);
 
-	start_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		start_media_player();
+	else
+		start_media_recorder();
 }
 
 static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
@@ -317,7 +424,10 @@ static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
 {
 	printf("%s\n", __func__);
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
 }
 
 static void close_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
@@ -326,7 +436,11 @@ static void close_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
 {
 	printf("%s\n", __func__);
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
+
 	avdtp_stream = NULL;
 }
 
@@ -336,7 +450,11 @@ static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *lsep,
 {
 	printf("%s\n", __func__);
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
+
 	avdtp_stream = NULL;
 }
 
@@ -466,7 +584,10 @@ static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *lsep,
 	if (reject)
 		return FALSE;
 
-	start_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		start_media_player();
+	else
+		start_media_recorder();
 
 	return TRUE;
 }
@@ -481,7 +602,10 @@ static gboolean suspend_ind(struct avdtp *session,
 	if (reject)
 		return FALSE;
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
 
 	return TRUE;
 }
@@ -495,7 +619,11 @@ static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 	if (reject)
 		return FALSE;
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
+
 	avdtp_stream = NULL;
 
 	return TRUE;
@@ -507,7 +635,11 @@ static void abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
 {
 	printf("%s\n", __func__);
 
-	stop_media_player();
+	if (dev_role == AVDTP_SEP_TYPE_SOURCE)
+		stop_media_player();
+	else
+		stop_media_recorder();
+
 	avdtp_stream = NULL;
 }
 
-- 
1.9.1


  parent reply	other threads:[~2014-08-29 13:17 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-08-29 13:17 [PATCH 1/6] android: Add initial code for AVDTP testing tool Szymon Janc
2014-08-29 13:17 ` [PATCH 2/6] android/avdtptest: Add support for streaming Szymon Janc
2014-08-29 13:17 ` [PATCH 3/6] android/avdtptest: Add option to reject commands Szymon Janc
2014-08-29 13:17 ` [PATCH 4/6] android/avdtptest: Add support for initiator role and discovery Szymon Janc
2014-08-29 13:17 ` [PATCH 5/6] android/avdtptest: Add support for fragmentation Szymon Janc
2014-08-29 13:17 ` Szymon Janc [this message]
2014-09-01 14:15 ` [PATCH 1/6] android: Add initial code for AVDTP testing tool Szymon Janc

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1409318278-798-6-git-send-email-szymon.janc@tieto.com \
    --to=szymon.janc@tieto.com \
    --cc=linux-bluetooth@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox