Diff between e02433c0b00b39d0a5184ddd17f37434719bcb52 and cf663b9f5a4f21d01a9b178f9b69ed20a26dfccf

Changed Files

File Additions Deletions Status
tools/l2test.c +39 -19 modified

Full Patch

diff --git a/tools/l2test.c b/tools/l2test.c
index ce512c1..9a7c809 100644
--- a/tools/l2test.c
+++ b/tools/l2test.c
@@ -28,6 +28,7 @@
 #endif
 
 #include <stdio.h>
+#include <stdbool.h>
 #include <errno.h>
 #include <ctype.h>
 #include <fcntl.h>
@@ -261,6 +262,37 @@ static void hexdump(unsigned char *s, unsigned long l)
 	}
 }
 
+static int getopts(int sk, struct l2cap_options *opts, bool connected)
+{
+	socklen_t optlen;
+	int err;
+
+	memset(opts, 0, sizeof(*opts));
+
+	if (bdaddr_type == BDADDR_BREDR || cid) {
+		optlen = sizeof(*opts);
+		return getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts, &optlen);
+	}
+
+	optlen = sizeof(opts->imtu);
+	err = getsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu, &optlen);
+	if (err < 0 || !connected)
+		return err;
+
+	optlen = sizeof(opts->omtu);
+	return getsockopt(sk, SOL_BLUETOOTH, BT_SNDMTU, &opts->omtu, &optlen);
+}
+
+static int setopts(int sk, struct l2cap_options *opts)
+{
+	if (bdaddr_type == BDADDR_BREDR || cid)
+		return setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts,
+								sizeof(opts));
+
+	return setsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu,
+							sizeof(opts->imtu));
+}
+
 static int do_connect(char *svr)
 {
 	struct sockaddr_l2 addr;
@@ -293,12 +325,9 @@ static int do_connect(char *svr)
 	}
 
 	/* Get default options */
-	memset(&opts, 0, sizeof(opts));
-	optlen = sizeof(opts);
-
-	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+	if (getopts(sk, &opts, false) < 0) {
 		syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)",
-							strerror(errno), errno);
+						strerror(errno), errno);
 		goto error;
 	}
 
@@ -311,7 +340,7 @@ static int do_connect(char *svr)
 	opts.txwin_size = txwin_size;
 	opts.max_tx = max_transmit;
 
-	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
+	if (setopts(sk, &opts) < 0) {
 		syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)",
 							strerror(errno), errno);
 		goto error;
@@ -403,10 +432,7 @@ static int do_connect(char *svr)
 	}
 
 	/* Get current options */
-	memset(&opts, 0, sizeof(opts));
-	optlen = sizeof(opts);
-
-	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+	if (getopts(sk, &opts, true) < 0) {
 		syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)",
 							strerror(errno), errno);
 		goto error;
@@ -534,10 +560,7 @@ static void do_listen(void (*handler)(int sk))
 	}
 
 	/* Get default options */
-	memset(&opts, 0, sizeof(opts));
-	optlen = sizeof(opts);
-
-	if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+	if (getopts(sk, &opts, false) < 0) {
 		syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)",
 							strerror(errno), errno);
 		goto error;
@@ -553,7 +576,7 @@ static void do_listen(void (*handler)(int sk))
 	opts.txwin_size = txwin_size;
 	opts.max_tx = max_transmit;
 
-	if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
+	if (setopts(sk, &opts) < 0) {
 		syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)",
 							strerror(errno), errno);
 		goto error;
@@ -632,10 +655,7 @@ static void do_listen(void (*handler)(int sk))
 		}
 
 		/* Get current options */
-		memset(&opts, 0, sizeof(opts));
-		optlen = sizeof(opts);
-
-		if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+		if (getopts(nsk, &opts, true) < 0) {
 			syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)",
 							strerror(errno), errno);
 			if (!defer_setup) {