Skip to contentSkip to conversation

sco: Integrate SCO socket option in user space.

PATCH New Frédéric Dalleau 1 participant 5 messages Jan 30, 2013

Subsystems (2)
lore
Share & tools
lore
#0 lore raw

cover sco: Integrate SCO socket option in user space.

Hi,

This is the required patches for taking advantage of SCO codec mode from userspace.

Regards,
Frédéric

Frédéric Dalleau (4):
lib: Declare mode field in sco_options
scotest: Add option for SCO socket mode
btio: Add option for SCO socket mode
btiotest: Add option for SCO socket mode

 btio/btio.c      |   11 ++++++++---
 btio/btio.h      |    1 +
 lib/sco.h        |    1 +
 tools/btiotest.c |   19 ++++++++++++++-----
 tools/scotest.c  |   36 ++++++++++++++++++++++++++++++++++--
 5 files changed, 58 insertions(+), 10 deletions(-)
Signature · 1 line
1.7.9.5
#1 lore raw

PATCH 1/4 lib: Declare mode field in sco_options

---
 lib/sco.h |    1 +
 1 file changed, 1 insertion(+)
lib/sco.h +1 -0
index 75336a5..c3a03ce 100644
@@ -47,6 +47,7 @@ struct sockaddr_sco {
 #define SCO_OPTIONS	0x01
 struct sco_options {
 	uint16_t	mtu;
+	uint8_t		mode;
 };
 
 #define SCO_CONNINFO	0x02
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/4 scotest: Add option for SCO socket mode

In reply to Frédéric Dalleau
---
 tools/scotest.c |   36 ++++++++++++++++++++++++++++++++++--
 1 file changed, 34 insertions(+), 2 deletions(-)
tools/scotest.c +34 -2
index a40e395..ea71c41 100644
@@ -58,6 +58,7 @@ static long data_size = 672;
 static bdaddr_t bdaddr;
 
 static int defer_setup = 0;
+static int mode = 0;
 
 static float tv2fl(struct timeval tv)
 {
@@ -68,6 +69,7 @@ static int do_connect(char *svr)
 {
 	struct sockaddr_sco addr;
 	struct sco_conninfo conn;
+	struct sco_options  opts;
 	socklen_t optlen;
 	int sk;
 
@@ -90,6 +92,15 @@ static int do_connect(char *svr)
 		goto error;
 	}
 
+	/* Add SCO options */
+	memset(&opts, 0, sizeof(opts));
+	opts.mode = mode;
+	if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0) {
+		syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+							strerror(errno), errno);
+		goto error;
+	}
+
 	/* Connect to remote device */
 	memset(&addr, 0, sizeof(addr));
 	addr.sco_family = AF_BLUETOOTH;
@@ -229,8 +240,16 @@ error:
 
 static void dump_mode(int sk)
 {
+	struct sco_options opts;
 	int len;
 
+	/* Add SCO options */
+	memset(&opts, 0, sizeof(opts));
+	opts.mode = mode;
+	if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0)
+		syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+							strerror(errno), errno);
+
 	if (defer_setup) {
 		len = read(sk, buf, sizeof(buf));
 		if (len < 0)
@@ -248,9 +267,17 @@ static void dump_mode(int sk)
 static void recv_mode(int sk)
 {
 	struct timeval tv_beg,tv_end,tv_diff;
+	struct sco_options opts;
 	long total;
 	int len;
 
+	/* Add SCO options */
+	memset(&opts, 0, sizeof(opts));
+	opts.mode = mode;
+	if (setsockopt(sk, SOL_SCO, SCO_OPTIONS, &opts, sizeof(opts)) < 0)
+		syslog(LOG_ERR, "Can't set socket options: %s (%d)",
+							strerror(errno), errno);
+
 	if (defer_setup) {
 		len = read(sk, buf, sizeof(buf));
 		if (len < 0)
@@ -381,7 +408,8 @@ static void usage(void)
 		"\t-n connect and be silent (client)\n"
 		"Options:\n"
 		"\t[-b bytes]\n"
-		"\t[-W seconds] enable deferred setup\n");
+		"\t[-W seconds] enable deferred setup\n"
+		"\t[-M mode] select mode (sco only: 0 cvsd, 1 transparent)\n");
 }
 
 int main(int argc ,char *argv[])
@@ -389,7 +417,7 @@ int main(int argc ,char *argv[])
 	struct sigaction sa;
 	int opt, sk, mode = RECV;
 
-	while ((opt = getopt(argc, argv, "rdscmnb:W:")) != EOF) {
+	while ((opt = getopt(argc, argv, "rdscmnb:W:M:")) != EOF) {
 		switch(opt) {
 		case 'r':
 			mode = RECV;
@@ -423,6 +451,10 @@ int main(int argc ,char *argv[])
 			defer_setup = atoi(optarg);
 			break;
 
+		case 'M':
+			mode = atoi(optarg);
+			break;
+
 		default:
 			usage();
 			exit(1);
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/4 btio: Add option for SCO socket mode

In reply to Frédéric Dalleau
---
 btio/btio.c |   11 ++++++++---
 btio/btio.h |    1 +
 2 files changed, 9 insertions(+), 3 deletions(-)
btio/btio.c +8 -3
index bbf1208..f9afc36 100644
@@ -77,6 +77,7 @@ struct set_opts {
 	uint8_t mode;
 	int flushable;
 	uint32_t priority;
+	uint8_t sco_mode;
 };
 
 struct connect {
@@ -720,7 +721,7 @@ static int sco_connect(int sock, const bdaddr_t *dst)
 	return 0;
 }
 
-static gboolean sco_set(int sock, uint16_t mtu, GError **err)
+static gboolean sco_set(int sock, uint16_t mtu, uint8_t mode, GError **err)
 {
 	struct sco_options sco_opt;
 	socklen_t len;
@@ -736,6 +737,7 @@ static gboolean sco_set(int sock, uint16_t mtu, GError **err)
 	}
 
 	sco_opt.mtu = mtu;
+	sco_opt.mode = mode;
 	if (setsockopt(sock, SOL_SCO, SCO_OPTIONS, &sco_opt,
 						sizeof(sco_opt)) < 0) {
 		ERROR_FAILED(err, "setsockopt(SCO_OPTIONS)", errno);
@@ -825,6 +827,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
 		case BT_IO_OPT_PRIORITY:
 			opts->priority = va_arg(args, int);
 			break;
+		case BT_IO_OPT_SCO_MODE:
+			opts->sco_mode = va_arg(args, int);
+			break;
 		default:
 			g_set_error(err, BT_IO_ERROR, EINVAL,
 					"Unknown option %d", opt);
@@ -1303,7 +1308,7 @@ gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...)
 	case BT_IO_RFCOMM:
 		return rfcomm_set(sock, opts.sec_level, opts.master, err);
 	case BT_IO_SCO:
-		return sco_set(sock, opts.mtu, err);
+		return sco_set(sock, opts.mtu, opts.sco_mode, err);
 	default:
 		g_set_error(err, BT_IO_ERROR, EINVAL,
 				"Unknown BtIO type %d", type);
@@ -1370,7 +1375,7 @@ static GIOChannel *create_io(gboolean server, struct set_opts *opts,
 		}
 		if (sco_bind(sock, &opts->src, err) < 0)
 			goto failed;
-		if (!sco_set(sock, opts->mtu, err))
+		if (!sco_set(sock, opts->mtu, opts->sco_mode, err))
 			goto failed;
 		break;
 	default:
btio/btio.h +1 -0
index a6ff5a2..e6ef990 100644
@@ -54,6 +54,7 @@ typedef enum {
 	BT_IO_OPT_MODE,
 	BT_IO_OPT_FLUSHABLE,
 	BT_IO_OPT_PRIORITY,
+	BT_IO_OPT_SCO_MODE,
 } BtIOOption;
 
 typedef enum {
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 4/4 btiotest: Add option for SCO socket mode

In reply to Frédéric Dalleau
---
 tools/btiotest.c |   19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
tools/btiotest.c +14 -5
index 7a77bb7..853d6d4 100644
@@ -436,7 +436,8 @@ static void rfcomm_listen(const char *src, uint8_t ch, gboolean defer,
 	g_io_channel_unref(rc_srv);
 }
 
-static void sco_connect(const char *src, const char *dst, gint disconn)
+static void sco_connect(const char *src, const char *dst, gint disconn,
+								gint mode)
 {
 	struct io_data *data;
 	GError *err = NULL;
@@ -451,12 +452,14 @@ static void sco_connect(const char *src, const char *dst, gint disconn)
 						&err,
 						BT_IO_OPT_SOURCE, src,
 						BT_IO_OPT_DEST, dst,
+						BT_IO_OPT_SCO_MODE, mode,
 						BT_IO_OPT_INVALID);
 	else
 		data->io = bt_io_connect(connect_cb, data,
 						(GDestroyNotify) io_data_unref,
 						&err,
 						BT_IO_OPT_DEST, dst,
+						BT_IO_OPT_SCO_MODE, mode,
 						BT_IO_OPT_INVALID);
 
 	if (!data->io) {
@@ -467,7 +470,7 @@ static void sco_connect(const char *src, const char *dst, gint disconn)
 }
 
 static void sco_listen(const char *src, gboolean defer, gint reject,
-				gint disconn, gint accept)
+				gint disconn, gint accept, gint mode)
 {
 	struct io_data *data;
 	BtIOConnect conn;
@@ -492,11 +495,14 @@ static void sco_listen(const char *src, gboolean defer, gint reject,
 					(GDestroyNotify) io_data_unref,
 					&err,
 					BT_IO_OPT_SOURCE, src,
+					BT_IO_OPT_SCO_MODE, mode,
 					BT_IO_OPT_INVALID);
 	else
 		sco_srv = bt_io_listen(conn, cfm, data,
 					(GDestroyNotify) io_data_unref,
-					&err, BT_IO_OPT_INVALID);
+					&err,
+					BT_IO_OPT_SCO_MODE, mode,
+					BT_IO_OPT_INVALID);
 
 	if (!sco_srv) {
 		printf("Listening failed: %s\n", err->message);
@@ -511,6 +517,7 @@ static gint opt_channel = -1;
 static gint opt_psm = 0;
 static gboolean opt_sco = FALSE;
 static gboolean opt_defer = FALSE;
+static gint opt_mode = 0;
 static char *opt_dev = NULL;
 static gint opt_reject = -1;
 static gint opt_disconn = -1;
@@ -537,6 +544,8 @@ static GOptionEntry options[] = {
 				"Use SCO" },
 	{ "defer", 'd', 0, G_OPTION_ARG_NONE, &opt_defer,
 				"Use DEFER_SETUP for incoming connections" },
+	{ "mode", 'M', 0, G_OPTION_ARG_NONE, &opt_mode,
+				"Use specified mode (0 CVSD, 1 Transparent)" },
 	{ "sec-level", 'S', 0, G_OPTION_ARG_INT, &opt_sec,
 				"Security level" },
 	{ "update-sec-level", 'U', 0, G_OPTION_ARG_INT, &opt_update_sec,
@@ -602,10 +611,10 @@ int main(int argc, char *argv[])
 
 	if (opt_sco) {
 		if (argc > 1)
-			sco_connect(opt_dev, argv[1], opt_disconn);
+			sco_connect(opt_dev, argv[1], opt_disconn, opt_mode);
 		else
 			sco_listen(opt_dev, opt_defer, opt_reject,
-					opt_disconn, opt_accept);
+					opt_disconn, opt_accept, opt_mode);
 	}
 
 	signal(SIGTERM, sig_term);
Signature · 1 line
1.7.9.5