Commit fa2f83bf authored by Krzysztof Kopyściński's avatar Krzysztof Kopyściński Committed by Carles Cufi
Browse files

Bluetooth: host: add testing API (disconnect one EATT channel)



To test fallback to remaining bearers PTS might request IUT to
disconnect one of the connected EATT channels, while the others remain
intact. Test function must be added, because we cannot create L2CAP
server on EATT PSM and manage this server as normal and have EATT
enabled at same time.

This is affecting GATT/SR/GAW/BV-14-C

Signed-off-by: default avatarKrzysztof Kopyściński <krzysztof.kopyscinski@codecoup.pl>
parent 7a687b8a
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -52,6 +52,10 @@ extern "C" {
/* 0xffff is defined as the maximum, and thus last, valid attribute handle */
#define BT_ATT_LAST_ATTTRIBUTE_HANDLE           0xffff

#if defined(CONFIG_BT_TESTING)
int bt_eatt_disconnect_one(struct bt_conn *conn);
#endif /* CONFIG_BT_TESTING */

#ifdef __cplusplus
}
#endif
+21 −0
Original line number Diff line number Diff line
@@ -2902,6 +2902,27 @@ int bt_eatt_disconnect(struct bt_conn *conn)
	return err;
}

#if defined(CONFIG_BT_TESTING)
int bt_eatt_disconnect_one(struct bt_conn *conn)
{
	struct bt_att_chan *chan = att_get_fixed_chan(conn);
	struct bt_att *att = chan->att;
	int err = -ENOTCONN;

	if (!conn) {
		return -EINVAL;
	}

	SYS_SLIST_FOR_EACH_CONTAINER(&att->chans, chan, node) {
		if (atomic_test_bit(chan->flags, ATT_ENHANCED)) {
			err = bt_l2cap_chan_disconnect(&chan->chan.chan);
			return err;
		}
	}

	return err;
}
#endif /* CONFIG_BT_TESTING */
#endif /* CONFIG_BT_EATT */

static int bt_eatt_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
+7 −0
Original line number Diff line number Diff line
@@ -787,6 +787,13 @@ struct l2cap_accept_connection_cmd {
	uint16_t result;
} __packed;

#define L2CAP_DISCONNECT_EATT_CHANS		0x09
struct l2cap_disconnect_eatt_chans_cmd {
	uint8_t address_type;
	uint8_t address[6];
	uint8_t count;
} __packed;

/* events */
#define L2CAP_EV_CONNECTION_REQ		0x80
struct l2cap_connection_req_ev {
+39 −1
Original line number Diff line number Diff line
@@ -10,6 +10,7 @@

#include <errno.h>
#include <bluetooth/l2cap.h>
#include <bluetooth/att.h>
#include <sys/byteorder.h>

#include <logging/log.h>
@@ -237,6 +238,39 @@ rsp:
		   status);
}


void disconnect_eatt_chans(uint8_t *data, uint16_t len)
{
	const struct l2cap_disconnect_eatt_chans_cmd *cmd = (void *) data;
	struct bt_conn *conn;
	int err;
	int status;

	conn = bt_conn_lookup_addr_le(BT_ID_DEFAULT, (bt_addr_le_t *)data);
	if (!conn) {
		LOG_ERR("Unknown connection");
		status = BTP_STATUS_FAILED;
		goto rsp;
	}

	for (int i = 0; i < cmd->count; i++) {
		err = bt_eatt_disconnect_one(conn);
		if (err) {
			status = BTP_STATUS_FAILED;
			goto rsp;
		}
	}

	status = BTP_STATUS_SUCCESS;

rsp:
	bt_conn_unref(conn);

	tester_rsp(BTP_SERVICE_ID_L2CAP, L2CAP_DISCONNECT_EATT_CHANS,
		   CONTROLLER_INDEX, status);
}


static void send_data(uint8_t *data, uint16_t len)
{
	const struct l2cap_send_data_cmd *cmd = (void *) data;
@@ -372,7 +406,7 @@ fail:

static void supported_commands(uint8_t *data, uint16_t len)
{
	uint8_t cmds[1];
	uint8_t cmds[2];
	struct l2cap_read_supported_commands_rp *rp = (void *) cmds;

	(void)memset(cmds, 0, sizeof(cmds));
@@ -382,6 +416,7 @@ static void supported_commands(uint8_t *data, uint16_t len)
	tester_set_bit(cmds, L2CAP_DISCONNECT);
	tester_set_bit(cmds, L2CAP_LISTEN);
	tester_set_bit(cmds, L2CAP_SEND_DATA);
	tester_set_bit(cmds, L2CAP_DISCONNECT_EATT_CHANS);

	tester_send(BTP_SERVICE_ID_L2CAP, L2CAP_READ_SUPPORTED_COMMANDS,
		    CONTROLLER_INDEX, (uint8_t *) rp, sizeof(cmds));
@@ -400,6 +435,9 @@ void tester_handle_l2cap(uint8_t opcode, uint8_t index, uint8_t *data,
	case L2CAP_DISCONNECT:
		disconnect(data, len);
		return;
	case L2CAP_DISCONNECT_EATT_CHANS:
		disconnect_eatt_chans(data, len);
		return;
	case L2CAP_SEND_DATA:
		send_data(data, len);
		return;