Bluetooth: Store device name

This uses bt_dev to store the name and allow changing it at runtime, in
addtion to that if CONFIG_BT_SETTINGS is defined make the name
persistent.

Fixes #8357

Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2018-07-09 15:12:04 +03:00 committed by Johan Hedberg
commit 2637c978fe
5 changed files with 126 additions and 33 deletions

View file

@ -56,6 +56,24 @@ typedef void (*bt_ready_cb_t)(int err);
*/ */
int bt_enable(bt_ready_cb_t cb); int bt_enable(bt_ready_cb_t cb);
/** @brief Set Bluetooth Device Name
*
* Set Bluetooth GAP Device Name.
*
* @param name New name
*
* @return Zero on success or (negative) error code otherwise.
*/
int bt_set_name(const char *name);
/** @brief Get Bluetooth Device Name
*
* Get Bluetooth GAP Device Name.
*
* @return Bluetooth Device Name
*/
const char *bt_get_name(void);
/** @brief Set the local Identity Address /** @brief Set the local Identity Address
* *
* Allows setting the local Identity Address from the application. * Allows setting the local Identity Address from the application.

View file

@ -334,6 +334,17 @@ config BT_SCAN_WITH_IDENTITY
disclosing local identity information. However, if the use case disclosing local identity information. However, if the use case
requires disclosing it then enable this option. requires disclosing it then enable this option.
config BT_DEVICE_NAME_MAX
int "Maximum size in bytes for device name"
default 28
default 0 if !BT_SETTINGS
range 0 248
help
Bluetooth device name storage size. Storage can be up to 248 bytes
long (excluding NULL termination). 0 means that no storage space is
allocated for device name in which case the device name cannot be
changed at runtime.
config BT_DEVICE_NAME config BT_DEVICE_NAME
string "Bluetooth device name" string "Bluetooth device name"
default "Zephyr" default "Zephyr"

View file

@ -19,6 +19,8 @@
#include <misc/__assert.h> #include <misc/__assert.h>
#include <soc.h> #include <soc.h>
#include <settings/settings.h>
#include <bluetooth/bluetooth.h> #include <bluetooth/bluetooth.h>
#include <bluetooth/conn.h> #include <bluetooth/conn.h>
#include <bluetooth/l2cap.h> #include <bluetooth/l2cap.h>
@ -4656,6 +4658,8 @@ int bt_enable(bt_ready_cb_t cb)
if (err) { if (err) {
return err; return err;
} }
} else {
bt_set_name(CONFIG_BT_DEVICE_NAME);
} }
ready_cb = cb; ready_cb = cb;
@ -4694,6 +4698,77 @@ int bt_enable(bt_ready_cb_t cb)
return 0; return 0;
} }
static int set_ad(u16_t hci_op, const struct bt_data *ad, size_t ad_len)
{
struct bt_hci_cp_le_set_adv_data *set_data;
struct net_buf *buf;
int i;
buf = bt_hci_cmd_create(hci_op, sizeof(*set_data));
if (!buf) {
return -ENOBUFS;
}
set_data = net_buf_add(buf, sizeof(*set_data));
memset(set_data, 0, sizeof(*set_data));
for (i = 0; i < ad_len; i++) {
/* Check if ad fit in the remaining buffer */
if (set_data->len + ad[i].data_len + 2 > 31) {
net_buf_unref(buf);
return -EINVAL;
}
set_data->data[set_data->len++] = ad[i].data_len + 1;
set_data->data[set_data->len++] = ad[i].type;
memcpy(&set_data->data[set_data->len], ad[i].data,
ad[i].data_len);
set_data->len += ad[i].data_len;
}
return bt_hci_cmd_send_sync(hci_op, buf, NULL);
}
int bt_set_name(const char *name)
{
#if CONFIG_BT_DEVICE_NAME_MAX > 0
size_t len = strlen(name);
int err;
if (len >= sizeof(bt_dev.name)) {
return -ENOMEM;
}
if (!strcmp(bt_dev.name, name)) {
return 0;
}
if (IS_ENABLED(CONFIG_BT_SETTINGS)) {
err = settings_save_one("bt/name", CONFIG_BT_DEVICE_NAME);
if (err) {
return err;
}
}
strncpy(bt_dev.name, name, sizeof(bt_dev.name));
return 0;
#else
return -ENOMEM;
#endif
}
const char *bt_get_name(void)
{
#if CONFIG_BT_DEVICE_NAME_MAX > 0
return bt_dev.name;
#else
return CONFIG_BT_DEVICE_NAME;
#endif
}
int bt_set_id_addr(const bt_addr_le_t *addr) int bt_set_id_addr(const bt_addr_le_t *addr)
{ {
if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) { if (atomic_test_bit(bt_dev.flags, BT_DEV_READY)) {
@ -4748,39 +4823,6 @@ static bool valid_adv_param(const struct bt_le_adv_param *param)
return true; return true;
} }
static int set_ad(u16_t hci_op, const struct bt_data *ad, size_t ad_len)
{
struct bt_hci_cp_le_set_adv_data *set_data;
struct net_buf *buf;
int i;
buf = bt_hci_cmd_create(hci_op, sizeof(*set_data));
if (!buf) {
return -ENOBUFS;
}
set_data = net_buf_add(buf, sizeof(*set_data));
memset(set_data, 0, sizeof(*set_data));
for (i = 0; i < ad_len; i++) {
/* Check if ad fit in the remaining buffer */
if (set_data->len + ad[i].data_len + 2 > 31) {
net_buf_unref(buf);
return -EINVAL;
}
set_data->data[set_data->len++] = ad[i].data_len + 1;
set_data->data[set_data->len++] = ad[i].type;
memcpy(&set_data->data[set_data->len], ad[i].data,
ad[i].data_len);
set_data->len += ad[i].data_len;
}
return bt_hci_cmd_send_sync(hci_op, buf, NULL);
}
int bt_le_adv_start(const struct bt_le_adv_param *param, int bt_le_adv_start(const struct bt_le_adv_param *param,
const struct bt_data *ad, size_t ad_len, const struct bt_data *ad, size_t ad_len,
const struct bt_data *sd, size_t sd_len) const struct bt_data *sd, size_t sd_len)

View file

@ -163,6 +163,9 @@ struct bt_dev {
/* Work used for RPA rotation */ /* Work used for RPA rotation */
struct k_delayed_work rpa_update; struct k_delayed_work rpa_update;
#endif #endif
/* Local Name */
char name[CONFIG_BT_DEVICE_NAME_MAX];
}; };
extern struct bt_dev bt_dev; extern struct bt_dev bt_dev;

View file

@ -121,6 +121,19 @@ static int set(int argc, char **argv, char *val)
return 0; return 0;
} }
if (!strcmp(argv[0], "name")) {
if (strlen(val) >= sizeof(bt_dev.name)) {
BT_ERR("Invalid length for device name in storage: name"
" will be truncated");
}
strncpy(bt_dev.name, val, sizeof(bt_dev.name) - 1);
bt_dev.name[sizeof(bt_dev.name) - 1] = '\0';
BT_DBG("Name set to %s", bt_dev.name);
return 0;
}
#if defined(CONFIG_BT_PRIVACY) #if defined(CONFIG_BT_PRIVACY)
if (!strcmp(argv[0], "irk")) { if (!strcmp(argv[0], "irk")) {
len = sizeof(bt_dev.irk); len = sizeof(bt_dev.irk);
@ -203,6 +216,12 @@ static int commit(void)
generate_static_addr(); generate_static_addr();
} }
#if CONFIG_BT_DEVICE_NAME_MAX > 0
if (bt_dev.name[0] == '\0') {
bt_set_name(CONFIG_BT_DEVICE_NAME);
}
#endif
#if defined(CONFIG_BT_PRIVACY) #if defined(CONFIG_BT_PRIVACY)
{ {
u8_t zero[16] = { 0 }; u8_t zero[16] = { 0 };