Skip to content

Commit

Permalink
Bluetooth: Add support for local name in scan rsp
Browse files Browse the repository at this point in the history
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 <michal.narajowski@codecoup.pl>
Signed-off-by: Szymon Janc <szymon.janc@codecoup.pl>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
  • Loading branch information
Michał Narajowski authored and Marcel Holtmann committed Sep 19, 2016
1 parent 1110a2d commit 7c295c4
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 10 deletions.
28 changes: 20 additions & 8 deletions net/bluetooth/hci_request.c
Original file line number Diff line number Diff line change
Expand Up @@ -971,14 +971,14 @@ void __hci_req_enable_advertising(struct hci_request *req)
hci_req_add(req, HCI_OP_LE_SET_ADV_ENABLE, sizeof(enable), &enable);
}

static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
static u8 append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)
{
u8 ad_len = 0;
size_t name_len;
int max_len;

max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
name_len = strlen(hdev->dev_name);
if (name_len > 0) {
size_t max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
if (name_len > 0 && max_len > 0) {

if (name_len > max_len) {
name_len = max_len;
Expand All @@ -997,22 +997,34 @@ static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
return ad_len;
}

static u8 create_default_scan_rsp_data(struct hci_dev *hdev, u8 *ptr)
{
return append_local_name(hdev, ptr, 0);
}

static u8 create_instance_scan_rsp_data(struct hci_dev *hdev, u8 instance,
u8 *ptr)
{
struct adv_info *adv_instance;
u32 instance_flags;
u8 scan_rsp_len = 0;

adv_instance = hci_find_adv_instance(hdev, instance);
if (!adv_instance)
return 0;

/* TODO: Set the appropriate entries based on advertising instance flags
* here once flags other than 0 are supported.
*/
instance_flags = adv_instance->flags;

memcpy(ptr, adv_instance->scan_rsp_data,
adv_instance->scan_rsp_len);

return adv_instance->scan_rsp_len;
scan_rsp_len += adv_instance->scan_rsp_len;
ptr += adv_instance->scan_rsp_len;

if (instance_flags & MGMT_ADV_FLAG_LOCAL_NAME)
scan_rsp_len = append_local_name(hdev, ptr, scan_rsp_len);

return scan_rsp_len;
}

void __hci_req_update_scan_rsp_data(struct hci_request *req, u8 instance)
Expand Down
46 changes: 44 additions & 2 deletions net/bluetooth/mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -3012,6 +3012,35 @@ static int user_passkey_neg_reply(struct sock *sk, struct hci_dev *hdev,
HCI_OP_USER_PASSKEY_NEG_REPLY, 0);
}

static void adv_expire(struct hci_dev *hdev, u32 flags)
{
struct adv_info *adv_instance;
struct hci_request req;
int err;

adv_instance = hci_find_adv_instance(hdev, hdev->cur_adv_instance);
if (!adv_instance)
return;

/* stop if current instance doesn't need to be changed */
if (!(adv_instance->flags & flags))
return;

cancel_adv_timeout(hdev);

adv_instance = hci_get_next_instance(hdev, adv_instance->instance);
if (!adv_instance)
return;

hci_req_init(&req, hdev);
err = __hci_req_schedule_adv_instance(&req, adv_instance->instance,
true);
if (err)
return;

hci_req_run(&req, NULL);
}

static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)
{
struct mgmt_cp_set_local_name *cp;
Expand All @@ -3027,13 +3056,17 @@ static void set_name_complete(struct hci_dev *hdev, u8 status, u16 opcode)

cp = cmd->param;

if (status)
if (status) {
mgmt_cmd_status(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME,
mgmt_status(status));
else
} else {
mgmt_cmd_complete(cmd->sk, hdev->id, MGMT_OP_SET_LOCAL_NAME, 0,
cp, sizeof(*cp));

if (hci_dev_test_flag(hdev, HCI_LE_ADV))
adv_expire(hdev, MGMT_ADV_FLAG_LOCAL_NAME);
}

mgmt_pending_remove(cmd);

unlock:
Expand Down Expand Up @@ -5885,6 +5918,7 @@ static u32 get_supported_adv_flags(struct hci_dev *hdev)
flags |= MGMT_ADV_FLAG_DISCOV;
flags |= MGMT_ADV_FLAG_LIMITED_DISCOV;
flags |= MGMT_ADV_FLAG_MANAGED_FLAGS;
flags |= MGMT_ADV_FLAG_LOCAL_NAME;

if (hdev->adv_tx_power != HCI_TX_POWER_INVALID)
flags |= MGMT_ADV_FLAG_TX_POWER;
Expand Down Expand Up @@ -5961,6 +5995,10 @@ static bool tlv_data_is_valid(struct hci_dev *hdev, u32 adv_flags, u8 *data,
tx_power_managed = true;
max_len -= 3;
}
} else {
/* at least 1 byte of name should fit in */
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
max_len -= 3;
}

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

if (adv_flags & MGMT_ADV_FLAG_TX_POWER)
max_len -= 3;
} else {
/* at least 1 byte of name should fit in */
if (adv_flags & MGMT_ADV_FLAG_LOCAL_NAME)
max_len -= 3;
}

return max_len;
Expand Down

0 comments on commit 7c295c4

Please sign in to comment.