Skip to content

Commit 7c295c4

Browse files
Michał Narajowskiholtmann
authored andcommitted
Bluetooth: Add support for local name in scan rsp
This patch enables appending local name to scan response data. If currently advertised instance has name flag set it is expired immediately. Signed-off-by: Michał Narajowski <[email protected]> Signed-off-by: Szymon Janc <[email protected]> Signed-off-by: Marcel Holtmann <[email protected]>
1 parent 1110a2d commit 7c295c4

File tree

2 files changed

+64
-10
lines changed

2 files changed

+64
-10
lines changed

net/bluetooth/hci_request.c

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -971,14 +971,14 @@ void __hci_req_enable_advertising(struct hci_request *req)
971971
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
972972
}
973973

974-
static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
974+
static u8 append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)
975975
{
976-
u8 ad_len = 0;
977976
size_t name_len;
977+
int max_len;
978978

979+
max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
979980
name_len = strlen(hdev->dev_name);
980-
if (name_len > 0) {
981-
size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
981+
if (name_len > 0 && max_len > 0) {
982982

983983
if (name_len > max_len) {
984984
name_len = max_len;
@@ -997,22 +997,34 @@ static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
997997
return ad_len;
998998
}
999999

1000+
static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
1001+
{
1002+
return append_local_name(hdev, ptr, 0);
1003+
}
1004+
10001005
static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
10011006
u8 *ptr)
10021007
{
10031008
struct adv_info *adv_instance;
1009+
u32 instance_flags;
1010+
u8 scan_rsp_len = 0;
10041011

10051012
adv_instance = hci_find_adv_instance(hdev, instance);
10061013
if (!adv_instance)
10071014
return 0;
10081015

1009-
/* TODO: Set the appropriate entries based on advertising instance flags
1010-
* here once flags other than 0 are supported.
1011-
*/
1016+
instance_flags = adv_instance->flags;
1017+
10121018
memcpy(ptr, adv_instance->scan_rsp_data,
10131019
adv_instance->scan_rsp_len);
10141020

1015-
return adv_instance->scan_rsp_len;
1021+
scan_rsp_len += adv_instance->scan_rsp_len;
1022+
ptr += adv_instance->scan_rsp_len;
1023+
1024+
if (instance_flags & MGMT_ADV_FLAG_LOCAL_NAME)
1025+
scan_rsp_len = append_local_name(hdev, ptr, scan_rsp_len);
1026+
1027+
return scan_rsp_len;
10161028
}
10171029

10181030
void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)

net/bluetooth/mgmt.c

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3012,6 +3012,35 @@ static int user_passkey_neg_reply(struct sock *sk, struct hci_dev *hdev,
30123012
HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
30133013
}
30143014

3015+
static void adv_expire(struct hci_dev *hdev, u32 flags)
3016+
{
3017+
struct adv_info *adv_instance;
3018+
struct hci_request req;
3019+
int err;
3020+
3021+
adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);
3022+
if (!adv_instance)
3023+
return;
3024+
3025+
/* stop if current instance doesn't need to be changed */
3026+
if (!(adv_instance->flags & flags))
3027+
return;
3028+
3029+
cancel_adv_timeout(hdev);
3030+
3031+
adv_instance = hci_get_next_instance(hdev, adv_instance->instance);
3032+
if (!adv_instance)
3033+
return;
3034+
3035+
hci_req_init(&req, hdev);
3036+
err = __hci_req_schedule_adv_instance(&req, adv_instance->instance,
3037+
true);
3038+
if (err)
3039+
return;
3040+
3041+
hci_req_run(&req, NULL);
3042+
}
3043+
30153044
static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
30163045
{
30173046
struct mgmt_cp_set_local_name *cp;
@@ -3027,13 +3056,17 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
30273056

30283057
cp = cmd->param;
30293058

3030-
if (status)
3059+
if (status) {
30313060
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
30323061
mgmt_status(status));
3033-
else
3062+
} else {
30343063
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
30353064
cp, sizeof(*cp));
30363065

3066+
if (hci_dev_test_flag(hdev, HCI_LE_ADV))
3067+
adv_expire(hdev, MGMT_ADV_FLAG_LOCAL_NAME);
3068+
}
3069+
30373070
mgmt_pending_remove(cmd);
30383071

30393072
unlock:
@@ -5885,6 +5918,7 @@ static u32 get_supported_adv_flags(struct hci_dev *hdev)
58855918
flags |= MGMT_ADV_FLAG_DISCOV;
58865919
flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
58875920
flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
5921+
flags |= MGMT_ADV_FLAG_LOCAL_NAME;
58885922

58895923
if (hdev->adv_tx_power != HCI_TX_POWER_INVALID)
58905924
flags |= MGMT_ADV_FLAG_TX_POWER;
@@ -5961,6 +5995,10 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
59615995
tx_power_managed = true;
59625996
max_len -= 3;
59635997
}
5998+
} else {
5999+
/* at least 1 byte of name should fit in */
6000+
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
6001+
max_len -= 3;
59646002
}
59656003

59666004
if (len > max_len)
@@ -6293,6 +6331,10 @@ static u8 tlv_data_max_len(u32 adv_flags, bool is_adv_data)
62936331

62946332
if (adv_flags & MGMT_ADV_FLAG_TX_POWER)
62956333
max_len -= 3;
6334+
} else {
6335+
/* at least 1 byte of name should fit in */
6336+
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
6337+
max_len -= 3;
62966338
}
62976339

62986340
return max_len;

0 commit comments

Comments
 (0)