tests: Bluetooth: Tester: Add support for scan parameters

Add new command to set scanning parameters, including scan window,
scan interval, and physical interface (1M and coded PHYs).

Signed-off-by: Petri Pitkanen <petri.pitkanen@silabs.com>
diff --git a/tests/bluetooth/tester/src/btp/btp_gap.h b/tests/bluetooth/tester/src/btp/btp_gap.h
index 7b6bc23..fb95e77 100644
--- a/tests/bluetooth/tester/src/btp/btp_gap.h
+++ b/tests/bluetooth/tester/src/btp/btp_gap.h
@@ -388,6 +388,16 @@
 	uint8_t data[];
 } __packed;
 
+#define BTP_GAP_PHY_LE_1M            0x01
+#define BTP_GAP_PHY_LE_CODED         0x02
+#define BTP_GAP_SET_DISCOVERY_PARAMS 0x2f
+struct btp_gap_le_set_discovery_params_cmd {
+	uint16_t interval;
+	uint16_t window;
+	uint8_t phy;   /* 1M and Coded */
+	uint8_t flags; /* For future use */
+} __packed;
+
 #define BTP_GAP_SET_RPA_TIMEOUT                 0x30
 struct btp_gap_set_rpa_timeout_cmd {
 	uint16_t rpa_timeout;
diff --git a/tests/bluetooth/tester/src/btp_gap.c b/tests/bluetooth/tester/src/btp_gap.c
index 86892d4..b60b82c 100644
--- a/tests/bluetooth/tester/src/btp_gap.c
+++ b/tests/bluetooth/tester/src/btp_gap.c
@@ -1197,6 +1197,48 @@
 }
 #endif /* CONFIG_BT_CLASSIC */
 
+static struct bt_le_scan_param scan_param = {
+	.type = BT_LE_SCAN_TYPE_PASSIVE,
+	.options = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
+	.interval = BT_GAP_SCAN_FAST_INTERVAL,
+	.window = BT_GAP_SCAN_FAST_WINDOW,
+	.timeout = 0,
+	.interval_coded = 0,
+	.window_coded = 0,
+};
+
+#define MIN_SCAN_WINDOW   0x04
+#define MIN_SCAN_INTERVAL 0x04
+#define MAX_SCAN_INTERVAL 0x4000
+#define MAX_SCAN_WINDOW   0x4000
+static uint8_t set_le_discovery_params(const void *cmd, uint16_t cmd_len, void *rsp,
+				       uint16_t *rsp_len)
+{
+	const struct btp_gap_le_set_discovery_params_cmd *cp = cmd;
+
+	if (!IN_RANGE(cp->interval, MIN_SCAN_INTERVAL, MAX_SCAN_INTERVAL) ||
+	    !IN_RANGE(cp->window, MIN_SCAN_WINDOW, MAX_SCAN_WINDOW)) {
+		LOG_ERR("Invalid discovery parameters interval %u window %u", cp->interval,
+			cp->window);
+		return BTP_STATUS_FAILED;
+	}
+
+	/* 1M default we do not need to test for it */
+	if ((cp->phy & ~(BTP_GAP_PHY_LE_1M | BTP_GAP_PHY_LE_CODED)) != 0) {
+		LOG_ERR("Invalid PHY %u", cp->phy);
+		return BTP_STATUS_FAILED;
+	}
+
+	scan_param.interval = cp->interval;
+	scan_param.window = cp->window;
+
+	if ((cp->phy & BTP_GAP_PHY_LE_CODED) != 0) {
+		scan_param.options |= BT_LE_SCAN_OPT_CODED;
+	}
+
+	return BTP_STATUS_SUCCESS;
+}
+
 static uint8_t start_discovery(const void *cmd, uint16_t cmd_len,
 			       void *rsp, uint16_t *rsp_len)
 {
@@ -1207,16 +1249,6 @@
 		return br_start_discovery(cp);
 	}
 
-	struct bt_le_scan_param scan_param = {
-		.type     = BT_LE_SCAN_TYPE_PASSIVE,
-		.options  = BT_LE_SCAN_OPT_FILTER_DUPLICATE,
-		.interval = BT_GAP_SCAN_FAST_INTERVAL,
-		.window   = BT_GAP_SCAN_FAST_WINDOW,
-		.timeout = 0,
-		.interval_coded = 0,
-		.window_coded = 0,
-	};
-
 	if (cp->flags & BTP_GAP_DISCOVERY_FLAG_LE_ACTIVE_SCAN) {
 		scan_param.type = BT_LE_SCAN_TYPE_ACTIVE;
 	}
@@ -2965,6 +2997,11 @@
 		.func = stop_advertising,
 	},
 	{
+		.opcode = BTP_GAP_SET_DISCOVERY_PARAMS,
+		.expect_len = sizeof(struct btp_gap_le_set_discovery_params_cmd),
+		.func = set_le_discovery_params,
+	},
+	{
 		.opcode = BTP_GAP_START_DISCOVERY,
 		.expect_len = sizeof(struct btp_gap_start_discovery_cmd),
 		.func = start_discovery,