bluetooth: host: add ability to load CCC settings on demand
This commits adds a BT_SETTINGS_CCC_LAZY_LOADING option to allow for CCC settings to be loaded on demand when a peer device connects in order to reduce memory usage. Signed-off-by: François Delawarde <fnde@oticon.com>
This commit is contained in:
parent
42eb629188
commit
a51986616e
3 changed files with 59 additions and 1 deletions
|
@ -551,7 +551,11 @@ ssize_t bt_gatt_attr_read_chrc(struct bt_conn *conn,
|
||||||
.properties = _props, })), \
|
.properties = _props, })), \
|
||||||
BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _value)
|
BT_GATT_ATTRIBUTE(_uuid, _perm, _read, _write, _value)
|
||||||
|
|
||||||
#define BT_GATT_CCC_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
|
#if IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)
|
||||||
|
#define BT_GATT_CCC_MAX (CONFIG_BT_MAX_CONN)
|
||||||
|
#else
|
||||||
|
#define BT_GATT_CCC_MAX (CONFIG_BT_MAX_PAIRED + CONFIG_BT_MAX_CONN)
|
||||||
|
#endif
|
||||||
|
|
||||||
/** @brief GATT CCC configuration entry.
|
/** @brief GATT CCC configuration entry.
|
||||||
* @param id Local identity, BT_ID_DEFAULT in most cases.
|
* @param id Local identity, BT_ID_DEFAULT in most cases.
|
||||||
|
|
|
@ -173,6 +173,15 @@ config BT_SETTINGS
|
||||||
instead of each subsystem doing it independently.
|
instead of each subsystem doing it independently.
|
||||||
|
|
||||||
if BT_SETTINGS
|
if BT_SETTINGS
|
||||||
|
config BT_SETTINGS_CCC_LAZY_LOADING
|
||||||
|
bool "Load CCC values from settings when peer connects"
|
||||||
|
default y
|
||||||
|
help
|
||||||
|
Load Client Configuration Characteristic setting right after a bonded
|
||||||
|
device connects.
|
||||||
|
Disabling this option will increase memory usage as CCC values for all
|
||||||
|
bonded devices will be loaded when calling settings_load.
|
||||||
|
|
||||||
config BT_SETTINGS_CCC_STORE_ON_WRITE
|
config BT_SETTINGS_CCC_STORE_ON_WRITE
|
||||||
bool "Store CCC value immediately after it has been written"
|
bool "Store CCC value immediately after it has been written"
|
||||||
help
|
help
|
||||||
|
|
|
@ -3585,6 +3585,11 @@ static void add_subscriptions(struct bt_conn *conn)
|
||||||
|
|
||||||
#endif /* CONFIG_BT_GATT_CLIENT */
|
#endif /* CONFIG_BT_GATT_CLIENT */
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)
|
||||||
|
static int ccc_set_direct(const char *key, size_t len, settings_read_cb read_cb,
|
||||||
|
void *cb_arg, void *param);
|
||||||
|
#endif /* CONFIG_BT_SETTINGS_CCC_LAZY_LOADING */
|
||||||
|
|
||||||
void bt_gatt_connected(struct bt_conn *conn)
|
void bt_gatt_connected(struct bt_conn *conn)
|
||||||
{
|
{
|
||||||
struct conn_data data;
|
struct conn_data data;
|
||||||
|
@ -3594,6 +3599,26 @@ void bt_gatt_connected(struct bt_conn *conn)
|
||||||
data.conn = conn;
|
data.conn = conn;
|
||||||
data.sec = BT_SECURITY_L1;
|
data.sec = BT_SECURITY_L1;
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)
|
||||||
|
/* Load CCC settings from backend if bonded */
|
||||||
|
if (bt_addr_le_is_bonded(conn->id, &conn->le.dst)) {
|
||||||
|
char key[BT_SETTINGS_KEY_MAX];
|
||||||
|
|
||||||
|
if (conn->id) {
|
||||||
|
char id_str[4];
|
||||||
|
|
||||||
|
u8_to_dec(id_str, sizeof(id_str), conn->id);
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
|
&conn->le.dst, id_str);
|
||||||
|
} else {
|
||||||
|
bt_settings_encode_key(key, sizeof(key), "ccc",
|
||||||
|
&conn->le.dst, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
settings_load_subtree_direct(key, ccc_set_direct, (void *)key);
|
||||||
|
}
|
||||||
|
#endif /* CONFIG_BT_SETTINGS_CCC_LAZY_LOADING */
|
||||||
|
|
||||||
bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);
|
bt_gatt_foreach_attr(0x0001, 0xffff, update_ccc, &data);
|
||||||
|
|
||||||
/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part C page 2192:
|
/* BLUETOOTH CORE SPECIFICATION Version 5.1 | Vol 3, Part C page 2192:
|
||||||
|
@ -4124,7 +4149,27 @@ static int ccc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if IS_ENABLED(CONFIG_BT_SETTINGS_CCC_LAZY_LOADING)
|
||||||
|
static int ccc_set_direct(const char *key, size_t len, settings_read_cb read_cb,
|
||||||
|
void *cb_arg, void *param)
|
||||||
|
{
|
||||||
|
const char *name;
|
||||||
|
|
||||||
|
BT_DBG("key: %s", log_strdup((const char *)param));
|
||||||
|
|
||||||
|
/* Only "bt/ccc" settings should ever come here */
|
||||||
|
if (!settings_name_steq((const char *)param, "bt/ccc", &name)) {
|
||||||
|
BT_ERR("Invalid key");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ccc_set(name, len, read_cb, cb_arg);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
/* Only register the ccc_set settings handler when not loading on-demand */
|
||||||
SETTINGS_STATIC_HANDLER_DEFINE(bt_ccc, "bt/ccc", NULL, ccc_set, NULL, NULL);
|
SETTINGS_STATIC_HANDLER_DEFINE(bt_ccc, "bt/ccc", NULL, ccc_set, NULL, NULL);
|
||||||
|
#endif /* CONFIG_BT_SETTINGS_CCC_LAZY_LOADING */
|
||||||
|
|
||||||
|
|
||||||
#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
|
#if defined(CONFIG_BT_GATT_SERVICE_CHANGED)
|
||||||
static int sc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
|
static int sc_set(const char *name, size_t len_rd, settings_read_cb read_cb,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue