* [PATCH v3 2/6] btio: Add mode to for Enhanced Credit Mode
2020-03-18 21:51 [PATCH v3 1/6] lib: Add definitions for Enhanced Credits Based Mode Luiz Augusto von Dentz
@ 2020-03-18 21:51 ` Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 3/6] l2test: Add support for BT_MODE_EXT_FLOWCTL Luiz Augusto von Dentz
` (3 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-03-18 21:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds BT_IO_MODE_EXT_FLOWCTL which directly maps to
BT_MODE_EXT_FLOWCTL.
---
btio/btio.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++------
btio/btio.h | 3 ++-
2 files changed, 55 insertions(+), 7 deletions(-)
diff --git a/btio/btio.c b/btio/btio.c
index db37b99da..e7b4db16b 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -630,18 +630,34 @@ static gboolean set_le_imtu(int sock, uint16_t imtu, GError **err)
return TRUE;
}
+static gboolean set_le_mode(int sock, uint8_t mode, GError **err)
+{
+ if (setsockopt(sock, SOL_BLUETOOTH, BT_MODE, &mode,
+ sizeof(mode)) < 0) {
+ ERROR_FAILED(err, "setsockopt(BT_MODE)", errno);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level,
uint16_t imtu, uint16_t omtu, uint8_t mode,
int master, int flushable, uint32_t priority,
GError **err)
{
if (imtu || omtu || mode) {
- gboolean ret;
+ gboolean ret = FALSE;
if (src_type == BDADDR_BREDR)
ret = set_l2opts(sock, imtu, omtu, mode, err);
- else
- ret = set_le_imtu(sock, imtu, err);
+ else {
+ if (imtu)
+ ret = set_le_imtu(sock, imtu, err);
+
+ if (ret && mode)
+ ret = set_le_mode(sock, mode, err);
+ }
if (!ret)
return ret;
@@ -980,6 +996,30 @@ static int get_phy(int sock, uint32_t *phy)
return 0;
}
+static int get_le_imtu(int sock, uint16_t *mtu)
+{
+ socklen_t len;
+
+ len = sizeof(*mtu);
+
+ if (getsockopt(sock, SOL_BLUETOOTH, BT_RCVMTU, mtu, &len) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static int get_le_mode(int sock, uint8_t *mode)
+{
+ socklen_t len;
+
+ len = sizeof(*mode);
+
+ if (getsockopt(sock, SOL_BLUETOOTH, BT_MODE, mode, &len) < 0)
+ return -errno;
+
+ return 0;
+}
+
static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
va_list args)
{
@@ -999,10 +1039,11 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
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)
+ if (get_le_imtu(sock, &l2o.imtu) == 0) {
+ /* Older kernels may not support BT_MODE */
+ get_le_mode(sock, &l2o.mode);
goto parse_opts;
+ }
/* Non-LE CoC enabled kernels will return one of these
* in which case we need to fall back to L2CAP_OPTIONS.
@@ -1644,6 +1685,12 @@ GIOChannel *bt_io_connect(BtIOConnect connect, gpointer user_data,
sock = g_io_channel_unix_get_fd(io);
+ /* Use DEFER_SETUP when connecting using Ext-Flowctl */
+ if (opts.mode == BT_IO_MODE_EXT_FLOWCTL && opts.defer) {
+ setsockopt(sock, SOL_BLUETOOTH, BT_DEFER_SETUP, &opts.defer,
+ sizeof(opts.defer));
+ }
+
switch (opts.type) {
case BT_IO_L2CAP:
err = l2cap_connect(sock, &opts.dst, opts.dst_type,
diff --git a/btio/btio.h b/btio/btio.h
index 41a017acb..461c43eb0 100644
--- a/btio/btio.h
+++ b/btio/btio.h
@@ -71,7 +71,8 @@ typedef enum {
BT_IO_MODE_RETRANS,
BT_IO_MODE_FLOWCTL,
BT_IO_MODE_ERTM,
- BT_IO_MODE_STREAMING
+ BT_IO_MODE_STREAMING,
+ BT_IO_MODE_EXT_FLOWCTL
} BtIOMode;
typedef void (*BtIOConfirm)(GIOChannel *io, gpointer user_data);
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 3/6] l2test: Add support for BT_MODE_EXT_FLOWCTL
2020-03-18 21:51 [PATCH v3 1/6] lib: Add definitions for Enhanced Credits Based Mode Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 2/6] btio: Add mode to for Enhanced Credit Mode Luiz Augusto von Dentz
@ 2020-03-18 21:51 ` Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 4/6] emulator/bthost: Add support for ECRED Connection request/response Luiz Augusto von Dentz
` (2 subsequent siblings)
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-03-18 21:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This enables using l2test to connect or listen with
BT_MODE_EXT_FLOWCTL.
---
tools/l2test.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/tools/l2test.c b/tools/l2test.c
index 8c6e08646..0d846ed93 100644
--- a/tools/l2test.c
+++ b/tools/l2test.c
@@ -143,13 +143,14 @@ struct lookup_table {
};
static struct lookup_table l2cap_modes[] = {
- { "basic", L2CAP_MODE_BASIC },
+ { "basic", BT_MODE_BASIC },
/* Not implemented
- { "flowctl", L2CAP_MODE_FLOWCTL },
- { "retrans", L2CAP_MODE_RETRANS },
+ { "flowctl", BT_MODE_FLOWCTL },
+ { "retrans", BT_MODE_RETRANS },
*/
- { "ertm", L2CAP_MODE_ERTM },
- { "streaming", L2CAP_MODE_STREAMING },
+ { "ertm", BT_MODE_ERTM },
+ { "streaming", BT_MODE_STREAMING },
+ { "ext-flowctl",BT_MODE_EXT_FLOWCTL },
{ 0 }
};
@@ -283,7 +284,7 @@ static int getopts(int sk, struct l2cap_options *opts, bool connected)
memset(opts, 0, sizeof(*opts));
- if (bdaddr_type == BDADDR_BREDR) {
+ if (bdaddr_type == BDADDR_BREDR || rfcmode) {
optlen = sizeof(*opts);
return getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts, &optlen);
}
@@ -303,6 +304,13 @@ static int setopts(int sk, struct l2cap_options *opts)
return setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts,
sizeof(*opts));
+ if (opts->mode) {
+ if (setsockopt(sk, SOL_BLUETOOTH, BT_MODE, &opts->mode,
+ sizeof(opts->mode)) < 0) {
+ return -errno;
+ }
+ }
+
return setsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu,
sizeof(opts->imtu));
}
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 4/6] emulator/bthost: Add support for ECRED Connection request/response
2020-03-18 21:51 [PATCH v3 1/6] lib: Add definitions for Enhanced Credits Based Mode Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 2/6] btio: Add mode to for Enhanced Credit Mode Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 3/6] l2test: Add support for BT_MODE_EXT_FLOWCTL Luiz Augusto von Dentz
@ 2020-03-18 21:51 ` Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 5/6] tools/l2cap-tester: Add test for Ext-Flowctl mode Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 6/6] gatt: Enable connecting to EATT channel using " Luiz Augusto von Dentz
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-03-18 21:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds support for ECRED Connection request/response which will be
used by l2cap-runner to test L2CAP_MODE_EXT_FLOWCTL mode.
---
emulator/bthost.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 72 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 6482bbecc..0fa283464 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -1773,6 +1773,69 @@ static bool l2cap_le_conn_rsp(struct bthost *bthost, struct btconn *conn,
return true;
}
+static bool l2cap_ecred_conn_req(struct bthost *bthost, struct btconn *conn,
+ uint8_t ident, const void *data, uint16_t len)
+{
+ const struct bt_l2cap_pdu_ecred_conn_req *req = data;
+ struct {
+ struct bt_l2cap_pdu_ecred_conn_rsp pdu;
+ uint16_t dcid[5];
+ } __attribute__ ((packed)) rsp;
+ uint16_t psm;
+ int num_scid, i = 0;
+
+ if (len < sizeof(*req))
+ return false;
+
+ psm = le16_to_cpu(req->psm);
+
+ memset(&rsp, 0, sizeof(rsp));
+
+ rsp.pdu.mtu = 64;
+ rsp.pdu.mps = 64;
+ rsp.pdu.credits = 1;
+
+ if (!bthost_find_l2cap_cb_by_psm(bthost, psm)) {
+ rsp.pdu.result = cpu_to_le16(0x0002); /* PSM Not Supported */
+ goto respond;
+ }
+
+ len -= sizeof(rsp.pdu);
+ num_scid = len / sizeof(*req->scid);
+
+ for (; i < num_scid; i++)
+ rsp.dcid[i] = cpu_to_le16(conn->next_cid++);
+
+respond:
+ l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_ECRED_CONN_RSP, ident, &rsp,
+ sizeof(rsp.pdu) + i * sizeof(*rsp.dcid));
+
+ return true;
+}
+
+static bool l2cap_ecred_conn_rsp(struct bthost *bthost, struct btconn *conn,
+ uint8_t ident, const void *data, uint16_t len)
+{
+ const struct {
+ const struct bt_l2cap_pdu_ecred_conn_rsp *pdu;
+ uint16_t scid[5];
+ } __attribute__ ((packed)) *rsp = data;
+ int num_scid, i;
+
+ if (len < sizeof(*rsp))
+ return false;
+
+ num_scid = len / sizeof(*rsp->scid);
+
+ for (i = 0; i < num_scid; i++)
+ /* TODO add L2CAP connection before with proper PSM */
+ bthost_add_l2cap_conn(bthost, conn, 0,
+ le16_to_cpu(rsp->scid[i]), 0);
+
+
+ return true;
+}
+
static void l2cap_le_sig(struct bthost *bthost, struct btconn *conn,
const void *data, uint16_t len)
{
@@ -1819,6 +1882,15 @@ static void l2cap_le_sig(struct bthost *bthost, struct btconn *conn,
ret = l2cap_le_conn_rsp(bthost, conn, hdr->ident,
data + sizeof(*hdr), hdr_len);
break;
+ case BT_L2CAP_PDU_ECRED_CONN_REQ:
+ ret = l2cap_ecred_conn_req(bthost, conn, hdr->ident,
+ data + sizeof(*hdr), hdr_len);
+ break;
+
+ case BT_L2CAP_PDU_ECRED_CONN_RSP:
+ ret = l2cap_ecred_conn_rsp(bthost, conn, hdr->ident,
+ data + sizeof(*hdr), hdr_len);
+ break;
default:
printf("Unknown L2CAP code 0x%02x\n", hdr->code);
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 5/6] tools/l2cap-tester: Add test for Ext-Flowctl mode
2020-03-18 21:51 [PATCH v3 1/6] lib: Add definitions for Enhanced Credits Based Mode Luiz Augusto von Dentz
` (2 preceding siblings ...)
2020-03-18 21:51 ` [PATCH v3 4/6] emulator/bthost: Add support for ECRED Connection request/response Luiz Augusto von Dentz
@ 2020-03-18 21:51 ` Luiz Augusto von Dentz
2020-03-18 21:51 ` [PATCH v3 6/6] gatt: Enable connecting to EATT channel using " Luiz Augusto von Dentz
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-03-18 21:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This adds tests for Ext-Flowctl which uses ECRED PDUs.
---
tools/l2cap-tester.c | 174 +++++++++++++++++++++++++++++++++----------
1 file changed, 136 insertions(+), 38 deletions(-)
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 945f82caf..ebbd29f11 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -61,6 +61,7 @@ struct l2cap_data {
uint16_t client_psm;
uint16_t server_psm;
uint16_t cid;
+ uint8_t mode;
int expect_err;
uint8_t send_cmd_code;
@@ -91,7 +92,7 @@ struct l2cap_data {
uint8_t *client_bdaddr;
bool server_not_advertising;
bool direct_advertising;
- bool close_one_socket;
+ bool close_1;
};
static void mgmt_debug(const char *str, void *user_data)
@@ -474,17 +475,17 @@ static const struct l2cap_data le_client_close_socket_test_2 = {
.server_not_advertising = true,
};
-static const struct l2cap_data le_client_two_sockets_same_client = {
+static const struct l2cap_data le_client_2_same_client = {
.client_psm = 0x0080,
.server_psm = 0x0080,
.server_not_advertising = true,
};
-static const struct l2cap_data le_client_two_sockets_close_one = {
+static const struct l2cap_data le_client_2_close_1 = {
.client_psm = 0x0080,
.server_psm = 0x0080,
.server_not_advertising = true,
- .close_one_socket = true,
+ .close_1 = true,
};
static const struct l2cap_data le_client_connect_nval_psm_test = {
@@ -549,6 +550,49 @@ static const struct l2cap_data le_att_server_success_test_1 = {
.cid = 0x0004,
};
+static const struct l2cap_data ext_flowctl_client_connect_success_test_1 = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+};
+
+static const struct l2cap_data ext_flowctl_client_connect_adv_success_test_1 = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+ .direct_advertising = true,
+};
+
+static const struct l2cap_data ext_flowctl_client_connect_success_test_2 = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+ .sec_level = BT_SECURITY_MEDIUM,
+};
+
+static const struct l2cap_data ext_flowctl_client_connect_reject_test_1 = {
+ .client_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+ .send_cmd = cmd_reject_rsp,
+ .send_cmd_len = sizeof(cmd_reject_rsp),
+ .expect_err = ECONNREFUSED,
+};
+
+static const struct l2cap_data ext_flowctl_client_2 = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+ .server_not_advertising = true,
+};
+
+static const struct l2cap_data ext_flowctl_client_2_close_1 = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mode = BT_MODE_EXT_FLOWCTL,
+ .server_not_advertising = true,
+ .close_1 = true,
+};
+
static void client_cmd_complete(uint16_t opcode, uint8_t status,
const void *param, uint8_t len,
void *user_data)
@@ -1031,7 +1075,7 @@ failed:
}
static int create_l2cap_sock(struct test_data *data, uint16_t psm,
- uint16_t cid, int sec_level)
+ uint16_t cid, int sec_level, uint8_t mode)
{
const struct l2cap_data *l2data = data->test_data;
const uint8_t *master_bdaddr;
@@ -1091,6 +1135,17 @@ static int create_l2cap_sock(struct test_data *data, uint16_t psm,
}
}
+ if (mode) {
+ if (setsockopt(sk, SOL_BLUETOOTH, BT_MODE, &mode,
+ sizeof(mode)) < 0) {
+ err = -errno;
+ tester_warn("Can't set mode: %s (%d)", strerror(errno),
+ errno);
+ close(sk);
+ return err;
+ }
+ }
+
return sk;
}
@@ -1212,7 +1267,8 @@ static void test_connect(const void *test_data)
hciemu_add_master_post_command_hook(data->hciemu,
direct_adv_cmd_complete, NULL);
- sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level,
+ l2data->mode);
if (sk < 0) {
tester_test_failed();
return;
@@ -1241,7 +1297,8 @@ static void test_connect_reject(const void *test_data)
const struct l2cap_data *l2data = data->test_data;
int sk;
- sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level,
+ l2data->mode);
if (sk < 0) {
tester_test_failed();
return;
@@ -1256,29 +1313,40 @@ static void test_connect_reject(const void *test_data)
close(sk);
}
-static void connect_socket(const uint8_t *client_bdaddr, int *sk_holder,
- GIOFunc connect_cb)
+static int connect_socket(const uint8_t *client_bdaddr, GIOFunc connect_cb,
+ bool defer)
{
struct test_data *data = tester_get_data();
const struct l2cap_data *l2data = data->test_data;
GIOChannel *io;
int sk;
- sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level);
+ sk = create_l2cap_sock(data, 0, l2data->cid, l2data->sec_level,
+ l2data->mode);
if (sk < 0) {
tester_print("Error in create_l2cap_sock");
tester_test_failed();
- return;
+ return -1;
}
- *sk_holder = sk;
+ if (defer) {
+ int opt = 1;
+
+ if (setsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, &opt,
+ sizeof(opt)) < 0) {
+ tester_print("Can't enable deferred setup: %s (%d)",
+ strerror(errno), errno);
+ tester_test_failed();
+ return -1;
+ }
+ }
if (connect_l2cap_impl(sk, client_bdaddr, BDADDR_LE_PUBLIC,
l2data->client_psm, l2data->cid) < 0) {
tester_print("Error in connect_l2cap_sock");
close(sk);
tester_test_failed();
- return;
+ return -1;
}
if (connect_cb) {
@@ -1290,7 +1358,10 @@ static void connect_socket(const uint8_t *client_bdaddr, int *sk_holder,
g_io_channel_unref(io);
}
- tester_print("Connect in progress, sk = %d", sk);
+ tester_print("Connect in progress, sk = %d %s", sk,
+ defer ? "(deferred)" : "");
+
+ return -1;
}
static gboolean test_close_socket_1_part_3(gpointer arg)
@@ -1457,11 +1528,11 @@ static void test_close_socket(const void *test_data)
else
client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
- connect_socket(client_bdaddr, &data->sk, NULL);
+ data->sk = connect_socket(client_bdaddr, NULL, false);
}
-static uint8_t test_two_sockets_connect_cb_cnt;
-static gboolean test_two_sockets_connect_cb(GIOChannel *io, GIOCondition cond,
+static uint8_t test_2_connect_cb_cnt;
+static gboolean test_2_connect_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
struct test_data *data = tester_get_data();
@@ -1485,15 +1556,15 @@ static gboolean test_two_sockets_connect_cb(GIOChannel *io, GIOCondition cond,
}
tester_print("Successfully connected");
- test_two_sockets_connect_cb_cnt++;
+ test_2_connect_cb_cnt++;
- if (test_two_sockets_connect_cb_cnt == 2) {
+ if (test_2_connect_cb_cnt == 2) {
close(data->sk);
close(data->sk2);
tester_test_passed();
}
- if (l2data->close_one_socket && test_two_sockets_connect_cb_cnt == 1) {
+ if (l2data->close_1 && test_2_connect_cb_cnt == 1) {
close(data->sk2);
tester_test_passed();
}
@@ -1510,16 +1581,16 @@ static gboolean enable_advertising(gpointer args)
return FALSE;
}
-static void test_connect_two_sockets_part_2(void)
+static void test_connect_2_part_2(void)
{
struct test_data *data = tester_get_data();
const struct l2cap_data *l2data = data->test_data;
const uint8_t *client_bdaddr;
client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
- connect_socket(client_bdaddr, &data->sk2, test_two_sockets_connect_cb);
+ data->sk2 = connect_socket(client_bdaddr, test_2_connect_cb, false);
- if (l2data->close_one_socket) {
+ if (l2data->close_1) {
tester_print("Closing first socket! %d", data->sk);
close(data->sk);
}
@@ -1528,7 +1599,7 @@ static void test_connect_two_sockets_part_2(void)
}
static uint8_t test_scan_enable_counter;
-static void test_connect_two_sockets_router(uint16_t opcode, const void *param,
+static void test_connect_2_router(uint16_t opcode, const void *param,
uint8_t length, void *user_data)
{
const struct bt_hci_cmd_le_set_scan_enable *scan_params = param;
@@ -1538,23 +1609,24 @@ static void test_connect_two_sockets_router(uint16_t opcode, const void *param,
scan_params->enable == true) {
test_scan_enable_counter++;
if (test_scan_enable_counter == 1)
- test_connect_two_sockets_part_2();
+ test_connect_2_part_2();
else if (test_scan_enable_counter == 2)
g_idle_add(enable_advertising, NULL);
}
}
-static void test_connect_two_sockets(const void *test_data)
+static void test_connect_2(const void *test_data)
{
struct test_data *data = tester_get_data();
const struct l2cap_data *l2data = data->test_data;
const uint8_t *client_bdaddr;
+ bool defer;
- test_two_sockets_connect_cb_cnt = 0;
+ test_2_connect_cb_cnt = 0;
test_scan_enable_counter = 0;
hciemu_add_master_post_command_hook(data->hciemu,
- test_connect_two_sockets_router, data);
+ test_connect_2_router, data);
if (l2data->server_psm) {
struct bthost *bthost = hciemu_client_get_host(data->hciemu);
@@ -1564,12 +1636,14 @@ static void test_connect_two_sockets(const void *test_data)
NULL, NULL);
}
+ defer = (l2data->mode == BT_MODE_EXT_FLOWCTL);
+
client_bdaddr = hciemu_get_client_bdaddr(data->hciemu);
- if (l2data->close_one_socket)
- connect_socket(client_bdaddr, &data->sk, NULL);
+ if (l2data->close_1)
+ data->sk = connect_socket(client_bdaddr, NULL, defer);
else
- connect_socket(client_bdaddr, &data->sk,
- test_two_sockets_connect_cb);
+ data->sk = connect_socket(client_bdaddr, test_2_connect_cb,
+ defer);
}
static gboolean l2cap_listen_cb(GIOChannel *io, GIOCondition cond,
@@ -1727,7 +1801,8 @@ static void test_server(const void *test_data)
if (l2data->server_psm || l2data->cid) {
sk = create_l2cap_sock(data, l2data->server_psm,
- l2data->cid, l2data->sec_level);
+ l2data->cid, l2data->sec_level,
+ l2data->mode);
if (sk < 0) {
tester_test_failed();
return;
@@ -1776,7 +1851,7 @@ static void test_getpeername_not_connected(const void *test_data)
socklen_t len;
int sk;
- sk = create_l2cap_sock(data, 0, 0, 0);
+ sk = create_l2cap_sock(data, 0, 0, 0, 0);
if (sk < 0) {
tester_test_failed();
return;
@@ -1902,14 +1977,14 @@ int main(int argc, char *argv[])
test_close_socket);
test_l2cap_le("L2CAP LE Client - Open two sockets",
- &le_client_two_sockets_same_client,
+ &le_client_2_same_client,
setup_powered_client,
- test_connect_two_sockets);
+ test_connect_2);
test_l2cap_le("L2CAP LE Client - Open two sockets close one",
- &le_client_two_sockets_close_one,
+ &le_client_2_close_1,
setup_powered_client,
- test_connect_two_sockets);
+ test_connect_2);
test_l2cap_le("L2CAP LE Client - Invalid PSM",
&le_client_connect_nval_psm_test,
@@ -1920,6 +1995,29 @@ int main(int argc, char *argv[])
setup_powered_server, test_server);
+ test_l2cap_le("L2CAP Ext-Flowctl Client - Success",
+ &ext_flowctl_client_connect_success_test_1,
+ setup_powered_client, test_connect);
+ test_l2cap_le("L2CAP Ext-Flowctl Client, Direct Advertising - Success",
+ &ext_flowctl_client_connect_adv_success_test_1,
+ setup_powered_client, test_connect);
+ test_l2cap_le("L2CAP Ext-Flowctl Client SMP - Success",
+ &ext_flowctl_client_connect_success_test_2,
+ setup_powered_client, test_connect);
+ test_l2cap_le("L2CAP Ext-Flowctl Client - Command Reject",
+ &ext_flowctl_client_connect_reject_test_1,
+ setup_powered_client, test_connect);
+
+ test_l2cap_le("L2CAP Ext-Flowctl Client - Open two sockets",
+ &ext_flowctl_client_2,
+ setup_powered_client,
+ test_connect_2);
+
+ test_l2cap_le("L2CAP Ext-Flowctl Client - Open two sockets close one",
+ &ext_flowctl_client_2_close_1,
+ setup_powered_client,
+ test_connect_2);
+
test_l2cap_le("L2CAP LE ATT Client - Success",
&le_att_client_connect_success_test_1,
setup_powered_client, test_connect);
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v3 6/6] gatt: Enable connecting to EATT channel using Ext-Flowctl mode
2020-03-18 21:51 [PATCH v3 1/6] lib: Add definitions for Enhanced Credits Based Mode Luiz Augusto von Dentz
` (3 preceding siblings ...)
2020-03-18 21:51 ` [PATCH v3 5/6] tools/l2cap-tester: Add test for Ext-Flowctl mode Luiz Augusto von Dentz
@ 2020-03-18 21:51 ` Luiz Augusto von Dentz
4 siblings, 0 replies; 6+ messages in thread
From: Luiz Augusto von Dentz @ 2020-03-18 21:51 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This makes use of BT_IO_MODE_EXT_FLOWCTL to connect to EATT channels.
---
src/gatt-client.c | 34 +++++++++++++++++++++++++++++-----
1 file changed, 29 insertions(+), 5 deletions(-)
diff --git a/src/gatt-client.c b/src/gatt-client.c
index 20efb7ae9..a9bfc2802 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -2182,9 +2182,13 @@ static void eatt_connect(struct btd_gatt_client *client)
ba2str(device_get_address(dev), addr);
- DBG("Connection attempt to: %s", addr);
-
for (i = bt_att_get_channels(att); i < main_opts.gatt_channels; i++) {
+ int defer_timeout = i + 1 < main_opts.gatt_channels ? 1 : 0;
+
+ DBG("Connection attempt to: %s defer %s", addr,
+ defer_timeout ? "true" : "false");
+
+ /* Attempt to connect using the Ext-Flowctl */
io = bt_io_connect(eatt_connect_cb, client, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR,
btd_adapter_get_address(adapter),
@@ -2194,15 +2198,35 @@ static void eatt_connect(struct btd_gatt_client *client)
device_get_address(dev),
BT_IO_OPT_DEST_TYPE,
device_get_le_address_type(dev),
+ BT_IO_OPT_MODE, BT_IO_MODE_EXT_FLOWCTL,
BT_IO_OPT_PSM, BT_ATT_EATT_PSM,
BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
BT_IO_OPT_MTU, main_opts.gatt_mtu,
+ BT_IO_OPT_DEFER_TIMEOUT, defer_timeout,
BT_IO_OPT_INVALID);
if (!io) {
- error("EATT bt_io_connect(%s): %s", addr,
- gerr->message);
g_error_free(gerr);
- return;
+ gerr = NULL;
+ /* Fallback to legacy LE Mode */
+ io = bt_io_connect(eatt_connect_cb, client, NULL, &gerr,
+ BT_IO_OPT_SOURCE_BDADDR,
+ btd_adapter_get_address(adapter),
+ BT_IO_OPT_SOURCE_TYPE,
+ btd_adapter_get_address_type(adapter),
+ BT_IO_OPT_DEST_BDADDR,
+ device_get_address(dev),
+ BT_IO_OPT_DEST_TYPE,
+ device_get_le_address_type(dev),
+ BT_IO_OPT_PSM, BT_ATT_EATT_PSM,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_MTU, main_opts.gatt_mtu,
+ BT_IO_OPT_INVALID);
+ if (!io) {
+ error("EATT bt_io_connect(%s): %s", addr,
+ gerr->message);
+ g_error_free(gerr);
+ return;
+ }
}
g_io_channel_unref(io);
--
2.21.1
^ permalink raw reply related [flat|nested] 6+ messages in thread