diff --git a/btio/btio.c b/btio/btio.c
index 7ef7ec7..f9b2507 100644
--- a/btio/btio.c
+++ b/btio/btio.c
(struct sockaddr *) &dst, sizeof(src), err))
return FALSE;
- len = sizeof(l2o);
- memset(&l2o, 0, len);
+ memset(&l2o, 0, sizeof(l2o));
if (src.l2_bdaddr_type != BDADDR_BREDR) {
+ len = sizeof(l2o.imtu);
if (getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU,
&l2o.imtu, &len) == 0)
goto parse_opts;
}
}
+ len = sizeof(l2o);
if (getsockopt(sock, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
ERROR_FAILED(err, "getsockopt(L2CAP_OPTIONS)", errno);
return FALSE;
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index fd6c5ea..ffa9223 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
tester_test_passed();
}
+static bool check_mtu(struct test_data *data, int sk)
+{
+ const struct l2cap_data *l2data = data->test_data;
+ struct l2cap_options l2o;
+ socklen_t len;
+
+ memset(&l2o, 0, sizeof(l2o));
+
+ if (data->hciemu_type == HCIEMU_TYPE_LE &&
+ (l2data->client_psm || l2data->server_psm)) {
+ /* LE CoC enabled kernels should support BT_RCVMTU and
+ * BT_SNDMTU.
+ */
+ len = sizeof(l2o.imtu);
+ if (getsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU,
+ &l2o.imtu, &len) < 0) {
+ tester_warn("getsockopt(BT_RCVMTU): %s (%d)",
+ strerror(errno), errno);
+ return false;
+ }
+
+ len = sizeof(l2o.omtu);
+ if (getsockopt(sk, SOL_BLUETOOTH, BT_SNDMTU,
+ &l2o.omtu, &len) < 0) {
+ tester_warn("getsockopt(BT_SNDMTU): %s (%d)",
+ strerror(errno), errno);
+ return false;
+ }
+ } else {
+ /* For non-LE CoC enabled kernels we need to fall back to
+ * L2CAP_OPTIONS, so test support for it as well */
+ len = sizeof(l2o);
+ if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
+ tester_warn("getsockopt(L2CAP_OPTIONS): %s (%d)",
+ strerror(errno), errno);
+ return false;
+ }
+ }
+
+ return true;
+}
+
static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
else
err = -sk_err;
- if (err < 0)
+ if (err < 0) {
tester_warn("Connect failed: %s (%d)", strerror(-err), -err);
- else
- tester_print("Successfully connected");
+ goto failed;
+ }
+
+ tester_print("Successfully connected");
+
+ if (!check_mtu(data, sk)) {
+ tester_test_failed();
+ return FALSE;
+ }
if (l2data->read_data) {
struct bthost *bthost;
return FALSE;
}
+failed:
if (-err != l2data->expect_err)
tester_test_failed();
else
return FALSE;
}
+ if (!check_mtu(data, new_sk)) {
+ tester_test_failed();
+ return FALSE;
+ }
+
if (l2data->read_data) {
struct bthost *bthost;
GIOChannel *new_io;