From bb271a6d9877f5358ce8c6af0b17f67c1a780835 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 24 Sep 2018 11:20:20 +0200 Subject: [PATCH] Bluetooth: Add option to configure peripheral connection parameters This allows to configure desired parameters for peripheral. When set PPCP characteristic is also added to GAP service. If disabled it is up to application to controll connection parameters and stack will only enforce 5 seconds delay before update. Signed-off-by: Szymon Janc --- subsys/bluetooth/host/Kconfig | 38 +++++++++++++++++++++++++++ subsys/bluetooth/host/conn.c | 29 +++++++++++++++++--- subsys/bluetooth/host/conn_internal.h | 1 + subsys/bluetooth/host/gatt.c | 25 ++++++++++++++++++ 4 files changed, 89 insertions(+), 4 deletions(-) diff --git a/subsys/bluetooth/host/Kconfig b/subsys/bluetooth/host/Kconfig index 05528e7760f98b..3deb160e04617c 100644 --- a/subsys/bluetooth/host/Kconfig +++ b/subsys/bluetooth/host/Kconfig @@ -349,6 +349,44 @@ config BT_MAX_PAIRED Maximum number of paired Bluetooth devices. The minimum (and default) number is 1. +config BT_GAP_PERIPHERAL_PREF_PARAMS + bool "Configure peripheral preferred connection parameters" + default y + depends on BT_PERIPHERAL + help + This allows to configure periphral preferred connection parameters. + Enabling this option results in adding PPCP characteristic in GAP + and sending request for connection parameters udpate after GAP + recommended 5 seconds of connection as peripheral. If disabled it is + up to application to set expected connection parameters. + +if BT_GAP_PERIPHERAL_PREF_PARAMS +config BT_PERIPHERAL_PREF_MIN_INT + int "Peripheral preferred minimum connection interval in 1.25ms units" + default 24 + range 6 3200 + +config BT_PERIPHERAL_PREF_MAX_INT + int "Peripheral preferred maximum connection interval in 1.25ms units" + default 40 + range 6 3200 + +config BT_PERIPHERAL_PREF_SLAVE_LATENCY + int "Peripheral preferred slave latency in Connection Intervals" + default 0 + range 0 499 + +config BT_PERIPHERAL_PREF_TIMEOUT + int "Peripheral preferred supervision timeout in 10ms units" + default 42 + range 10 3200 + help + It is up to user to provide valid timeout which pass required minimum + value: in milliseconds it shall be larger than + "(1+ Conn_Latency) * Conn_Interval_Max * 2" + where Conn_Interval_Max is given in milliseconds. +endif # BT_GAP_PERIPHERAL_PREF_PARAMS + endif # BT_CONN config BT_SCAN_WITH_IDENTITY diff --git a/subsys/bluetooth/host/conn.c b/subsys/bluetooth/host/conn.c index 74c61d54d93260..6613443a809b4c 100644 --- a/subsys/bluetooth/host/conn.c +++ b/subsys/bluetooth/host/conn.c @@ -230,12 +230,32 @@ static void conn_le_update_timeout(struct k_work *work) return; } - param = BT_LE_CONN_PARAM(conn->le.interval_min, - conn->le.interval_max, - conn->le.latency, - conn->le.timeout); +#if defined (CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS) + /* if application set own params use those, otherwise use defaults */ + if (atomic_test_and_clear_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET)) { + param = BT_LE_CONN_PARAM(conn->le.interval_min, + conn->le.interval_max, + conn->le.latency, + conn->le.timeout); + } else { + param = BT_LE_CONN_PARAM(CONFIG_BT_PERIPHERAL_PREF_MIN_INT, + CONFIG_BT_PERIPHERAL_PREF_MAX_INT, + CONFIG_BT_PERIPHERAL_PREF_SLAVE_LATENCY, + CONFIG_BT_PERIPHERAL_PREF_TIMEOUT); + } send_conn_le_param_update(conn, param); +#else + /* update only if application set own params */ + if (atomic_test_and_clear_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET)) { + param = BT_LE_CONN_PARAM(conn->le.interval_min, + conn->le.interval_max, + conn->le.latency, + conn->le.timeout); + + send_conn_le_param_update(conn, param); + } +#endif atomic_set_bit(conn->flags, BT_CONN_SLAVE_PARAM_UPDATE); } @@ -1796,6 +1816,7 @@ int bt_conn_le_param_update(struct bt_conn *conn, conn->le.interval_max = param->interval_max; conn->le.latency = param->latency; conn->le.timeout = param->timeout; + atomic_set_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET); } return 0; diff --git a/subsys/bluetooth/host/conn_internal.h b/subsys/bluetooth/host/conn_internal.h index e7096b791e2fcb..887e163c67397e 100644 --- a/subsys/bluetooth/host/conn_internal.h +++ b/subsys/bluetooth/host/conn_internal.h @@ -28,6 +28,7 @@ enum { BT_CONN_AUTO_PHY_UPDATE, /* Auto-update PHY */ BT_CONN_AUTO_DATA_LEN, /* Auto data len change in progress */ BT_CONN_SLAVE_PARAM_UPDATE, /* If slave param update timer fired */ + BT_CONN_SLAVE_PARAM_SET, /* If slave param were set from app */ /* Total number of flags - must be at the end of the enum */ BT_CONN_NUM_FLAGS, diff --git a/subsys/bluetooth/host/gatt.c b/subsys/bluetooth/host/gatt.c index 205ee7e51519af..d3bea364afe926 100644 --- a/subsys/bluetooth/host/gatt.c +++ b/subsys/bluetooth/host/gatt.c @@ -96,6 +96,27 @@ static ssize_t read_appearance(struct bt_conn *conn, sizeof(appearance)); } +#if defined (CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS) +static ssize_t read_ppcp(struct bt_conn *conn, const struct bt_gatt_attr *attr, + void *buf, u16_t len, u16_t offset) +{ + struct __packed { + uint16_t min_int; + uint16_t max_int; + uint16_t latency; + uint16_t timeout; + } ppcp; + + ppcp.min_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MIN_INT); + ppcp.max_int = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_MAX_INT); + ppcp.latency = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_SLAVE_LATENCY); + ppcp.timeout = sys_cpu_to_le16(CONFIG_BT_PERIPHERAL_PREF_TIMEOUT); + + return bt_gatt_attr_read(conn, attr, buf, len, offset, &ppcp, + sizeof(ppcp)); +} +#endif + #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY) static ssize_t read_central_addr_res(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, @@ -127,6 +148,10 @@ static struct bt_gatt_attr gap_attrs[] = { BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_central_addr_res, NULL, NULL), #endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */ +#if defined(CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS) + BT_GATT_CHARACTERISTIC(BT_UUID_GAP_PPCP, BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, read_ppcp, NULL, NULL), +#endif }; static struct bt_gatt_service gap_svc = BT_GATT_SERVICE(gap_attrs);