Skip to content

Conversation

@theob-pro
Copy link
Contributor

Introduce new threads safe and less confusing APIs to get/set the Bluetooth GAP Device Name.

Deprecate the old APIs and update the code base to use the new APIs.

If dynamic Bluetooth device name was enabled but the name was never set
with `bt_set_name`, we would then store the name set using
`CONFIG_BT_DEVICE_NAME`.

This can be really confusing because it mean that if someone change the
value of `CONFIG_BT_DEVICE_NAME` later on, and flash their device, the
old name would still be the one stored in the setting and being used.

By not storing it here, users will now have to explicitly set a name
using `bt_set_name` when using dynamic Bluetooth device name.

Signed-off-by: Théo Battrel <[email protected]>
No longer use `CONFIG_BT_DEVICE_NAME` to set the name when using dynamic
device name at Bluetooth initialization and when settings are disabled.

This can lead to confusion. When using dynamic device name user will
have to explicitly set the GAP device name.

Signed-off-by: Théo Battrel <[email protected]>
Introduce new shiny APIs to get and set the Bluetooth GAP Device Name.
The following two functions have been added:

- `bt_gap_get_device_name`
- `bt_gap_set_device_name`

Those new APIs are ✨ threads safe ✨ and handle Bluetooth GAP Device Name
containing '\0'. To do that they work with byte array instead of char
array.

Signed-off-by: Théo Battrel <[email protected]>
@theob-pro theob-pro force-pushed the new-gap-dev-name-api branch 3 times, most recently from c2f125b to 3a284b2 Compare April 22, 2025 13:00

dev_name:
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT_USE_DEVICE_NAME)) {
uint8_t name[BT_GAP_DEVICE_NAME_MAX_SIZE];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure after {} name array will disappear and stack might be used for anything else. Device might have garbage instead of name.

Even more, if you allocate memory on stack within this function, after leaving it the stack will be released and name will be again garbage.

This memory should be kept until Host copies in its buffer or global.
Probably place where struct bt_data is allocated should be sufficient.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I did the update too quickly. It should be good now.


dev_name:
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT_USE_DEVICE_NAME)) {
uint8_t name[BT_GAP_DEVICE_NAME_MAX_SIZE];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be nice to have BT_GAP_DEVICE_NAME_MAX_SIZE configured over KConfig despite it has specified size. I doubt in that all customers will consume all 237 bytes. Due to this, mesh functions will have stack memory overconsumption.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I created DEVICE_NAME_SIZE in mesh/gatt.h which conditionally take the value of BT_GAP_DEVICE_NAME_MAX_SIZE or CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC_MAX if CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC is enabled.

dev_name:
if (IS_ENABLED(CONFIG_BT_MESH_PB_GATT_USE_DEVICE_NAME)) {
uint8_t name[BT_GAP_DEVICE_NAME_MAX_SIZE];
size_t name_size = bt_gap_get_device_name(name, sizeof(name));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

-ENOMEM should be checked and\or converted to zero.

Could it be static assertion instead of size checking?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a check, I don't think that using assertion would be right here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@PavelVPV, would you have quite a look at this diff either?

@theob-pro theob-pro force-pushed the new-gap-dev-name-api branch 2 times, most recently from 7039fe9 to e43e524 Compare April 22, 2025 14:43
Update the Host subsys functions using the GAP Device Name to use the
new APIs.

Signed-off-by: Théo Battrel <[email protected]>
Update the Mesh functions using the GAP Device Name to use the new APIs.

Signed-off-by: Théo Battrel <[email protected]>
@theob-pro theob-pro force-pushed the new-gap-dev-name-api branch 4 times, most recently from e995b1e to aa04032 Compare April 22, 2025 18:46
Update samples to use the new Bluetooth GAP Device name APIs added in a
previous commit.

Signed-off-by: Théo Battrel <[email protected]>
Update the Bluetooth Host tests that uses the GAP Device Name to use the
new APIs.

Signed-off-by: Théo Battrel <[email protected]>
The following Kconfig APIs are deprecated:

- `CONFIG_BT_DEVICE_NAME`
- `CONFIG_BT_DEVICE_DYNAMIC`
- `CONFIG_BT_DEVICE_NAME_MAX`

The following C APIs are deprecated:

- `bt_get_name()`
- `bt_set_name()`

They are deprecated because the current APIs are not thread safe and can
be confusing.

The Kconfig APIs are replaced by the `BT_GAP_DEVICE_NAME_TYPE` choice.
When selecting `CONFIG_BT_GAP_DEVICE_NAME_STATIC`, the name must be set
using `CONFIG_BT_GAP_DEVICE_NAME`.

When selecting `CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC`, the GAP device name
must be set using `bt_gap_set_device_name()` and retrieved using
`bt_gap_get_device_name()`. The the maximum size of the GAP device name
can now be set using `CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC_MAX`.

Signed-off-by: Théo Battrel <[email protected]>
@theob-pro theob-pro force-pushed the new-gap-dev-name-api branch from aa04032 to 67ef981 Compare April 22, 2025 19:03
Copy link
Contributor

@PavelVPV PavelVPV left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know it is in the draft state but will put my comments here to not forget them.

I think there is a confusion in the new API usage.

By reading the API description and the code, it is assumed that the name (which is called as buf) is not a string (copied using memcpy, second argument to new functions called size, not length). So I assume (and as I see in the changes) a user must exclude NULL-terminator from the buf's size when passing it to the new API (they can't just use strlen, for example). However, I see also that a string literals are used as they were used before in Kconfig options (e.g. CONFIG_BT_GAP_DEVICE_NAME="sdp_client") which automatically includes NULL-terminator.

Also, the previous API was assuming name to be a string, so the new API doesn't fully match to the old one, which requires a migration guide.

I think it would be better for user experience if the new API matches the old one with regards to NULL-terminator. It is much more beneficial and less bug-prone for users.

Comment on lines +34 to +35
LOG_DBG("Device name is too big for the provided buffer.");
return -ENOMEM;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

k_mutex_unlock is missing.

int err;

if (size > BT_GAP_DEVICE_NAME_MAX_SIZE) {
return -ENOBUFS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't EINVAL be more appropriate here as showing that the argument is incorrect? ENOBUFS more related to pools.

Comment on lines +527 to +528
size_t name_size = bt_gap_get_device_name(name, sizeof(name));
if (name_size < 0) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

size_t can't be negative. Below as well.

uint8_t name[DEVICE_NAME_SIZE];
size_t name_size = bt_gap_get_device_name(name, sizeof(name));
if (name_size < 0) {
LOG_DBG("Failed to get name (err %d)", name_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
LOG_DBG("Failed to get name (err %d)", name_size);
LOG_ERR("Failed to get name (err %d)", name_size);

Below as well.

Comment on lines 635 to +637
sd[0].type = BT_DATA_NAME_COMPLETE;
sd[0].data_len = BT_DEVICE_NAME_LEN;
sd[0].data = BT_DEVICE_NAME;
sd[0].data_len = name_size;
sd[0].data = name;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not going to work, the name will be invalid after the block.

Comment on lines +295 to +301
size_t device_name_size = bt_gap_get_device_name(device_name, sizeof(device_name));
if (device_name_size < 0) {
LOG_DBG("Failed to get name (err %d)", device_name_size);
return -ENOMEM;
}

prov_sd_len = gatt_prov_adv_create(prov_sd, device_name, device_name_size);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code shows how the old option (BT_LE_ADV_OPT_USE_NAME and BT_LE_ADV_OPT_FORCE_NAME_IN_AD) that auto-included device name in advs and scan responses was so useful even though it was not intended behavior (though could be converted to). Now users should include the name manually allocating extra space on stack, doing memcpy, etc while host could do this under the hood more optimal. We didn't gain anything from removing that feature, but created more problems for users really.

Comment on lines +17 to +20
#if defined(CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC)
#define DEVICE_NAME_SIZE CONFIG_BT_GAP_DEVICE_NAME_DYNAMIC_MAX
#else
#define DEVICE_NAME_SIZE BT_GAP_DEVICE_NAME_MAX_SIZE
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we change this API, do we really need split between dynamic and not-dynamic name lengths? Can't we use one as a Kconfig option limiting its range through range option?

@github-actions
Copy link

This pull request has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this pull request will automatically be closed in 14 days. Note, that you can always re-open a closed pull request at any time.

@github-actions github-actions bot added the Stale label Jun 23, 2025
@theob-pro theob-pro closed this Jun 30, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants