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 <szymon.janc@codecoup.pl>
This commit is contained in:
Szymon Janc 2018-09-24 11:20:20 +02:00 committed by Johan Hedberg
commit bb271a6d98
4 changed files with 89 additions and 4 deletions

View file

@ -349,6 +349,44 @@ config BT_MAX_PAIRED
Maximum number of paired Bluetooth devices. The minimum (and Maximum number of paired Bluetooth devices. The minimum (and
default) number is 1. 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 endif # BT_CONN
config BT_SCAN_WITH_IDENTITY config BT_SCAN_WITH_IDENTITY

View file

@ -230,12 +230,32 @@ static void conn_le_update_timeout(struct k_work *work)
return; return;
} }
param = BT_LE_CONN_PARAM(conn->le.interval_min, #if defined (CONFIG_BT_GAP_PERIPHERAL_PREF_PARAMS)
conn->le.interval_max, /* if application set own params use those, otherwise use defaults */
conn->le.latency, if (atomic_test_and_clear_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET)) {
conn->le.timeout); 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); 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); 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.interval_max = param->interval_max;
conn->le.latency = param->latency; conn->le.latency = param->latency;
conn->le.timeout = param->timeout; conn->le.timeout = param->timeout;
atomic_set_bit(conn->flags, BT_CONN_SLAVE_PARAM_SET);
} }
return 0; return 0;

View file

@ -28,6 +28,7 @@ enum {
BT_CONN_AUTO_PHY_UPDATE, /* Auto-update PHY */ BT_CONN_AUTO_PHY_UPDATE, /* Auto-update PHY */
BT_CONN_AUTO_DATA_LEN, /* Auto data len change in progress */ 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_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 */ /* Total number of flags - must be at the end of the enum */
BT_CONN_NUM_FLAGS, BT_CONN_NUM_FLAGS,

View file

@ -96,6 +96,27 @@ static ssize_t read_appearance(struct bt_conn *conn,
sizeof(appearance)); 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) #if defined(CONFIG_BT_CENTRAL) && defined(CONFIG_BT_PRIVACY)
static ssize_t read_central_addr_res(struct bt_conn *conn, static ssize_t read_central_addr_res(struct bt_conn *conn,
const struct bt_gatt_attr *attr, void *buf, 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, BT_GATT_CHRC_READ, BT_GATT_PERM_READ,
read_central_addr_res, NULL, NULL), read_central_addr_res, NULL, NULL),
#endif /* CONFIG_BT_CENTRAL && CONFIG_BT_PRIVACY */ #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); static struct bt_gatt_service gap_svc = BT_GATT_SERVICE(gap_attrs);