diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index 713b9aa..b50a9c0 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
DBG("Failed to send request to read appearance");
}
+static void read_ppcp_cb(bool success, uint8_t att_ecode,
+ const uint8_t *value, uint16_t length,
+ void *user_data)
+{
+ struct gas *gas = user_data;
+ uint16_t min_interval, max_interval, latency, timeout, max_latency;
+
+ if (!success) {
+ DBG("Reading PPCP failed with ATT error: %u", att_ecode);
+ return;
+ }
+
+ if (length != 8) {
+ DBG("Malformed PPCP value");
+ return;
+ }
+
+ min_interval = get_le16(&value[0]);
+ max_interval = get_le16(&value[2]);
+ latency = get_le16(&value[4]);
+ timeout = get_le16(&value[6]);
+
+ DBG("GAP Peripheral Preferred Connection Parameters:");
+ DBG("\tMinimum connection interval: %u", min_interval);
+ DBG("\tMaximum connection interval: %u", max_interval);
+ DBG("\tSlave latency: %u", latency);
+ DBG("\tConnection Supervision timeout multiplier: %u", timeout);
+
+ /* 0xffff indicates no specific min/max */
+ if (min_interval == 0xffff)
+ min_interval = 6;
+
+ if (max_interval == 0xffff)
+ max_interval = 3200;
+
+ /* avoid persisting connection parameters that are not valid */
+ if (min_interval > max_interval ||
+ min_interval < 6 || max_interval > 3200) {
+ warn("GAS PPCP: Invalid Connection Parameters values");
+ return;
+ }
+
+ if (timeout < 10 || timeout > 3200) {
+ warn("GAS PPCP: Invalid Connection Parameters values");
+ return;
+ }
+
+ if (max_interval >= timeout * 8) {
+ warn("GAS PPCP: Invalid Connection Parameters values");
+ return;
+ }
+
+ max_latency = (timeout * 4 / max_interval) - 1;
+ if (latency > 499 || latency > max_latency) {
+ warn("GAS PPCP: Invalid Connection Parameters values");
+ return;
+ }
+
+ btd_device_set_conn_param(gas->device, min_interval, max_interval,
+ latency, timeout);
+}
+
+static void handle_ppcp(struct gas *gas, uint16_t value_handle)
+{
+ if (!bt_gatt_client_read_value(gas->client, value_handle,
+ read_ppcp_cb, gas, NULL))
+ DBG("Failed to send request to read PPCP");
+}
+
static inline bool uuid_cmp(uint16_t u16, const bt_uuid_t *uuid)
{
bt_uuid_t lhs;
handle_device_name(gas, value_handle);
else if (uuid_cmp(GATT_CHARAC_APPEARANCE, &uuid))
handle_appearance(gas, value_handle);
+ else if (uuid_cmp(GATT_CHARAC_PERIPHERAL_PREF_CONN, &uuid))
+ handle_ppcp(gas, value_handle);
else {
char uuid_str[MAX_LEN_UUID_STR];