summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichał Narajowski <michal.narajowski@codecoup.pl>2016-10-05 12:28:25 +0200
committerMarcel Holtmann <marcel@holtmann.org>2016-10-06 11:52:29 +0200
commitcecbf3e932c1fa6df45fd6cc4fc8081a4cb45bcd (patch)
tree4df2361cce3e715ab0cfa7bf6e4bbf4a35ec7853
parent1165df0ee470930c2da73def005b1f842c2239cc (diff)
downloadlinux-cecbf3e932c1fa6df45fd6cc4fc8081a4cb45bcd.tar.bz2
Bluetooth: Fix local name in scan rsp
Use complete name if it fits. If not and there is short name check if it fits. If not then use shortened name as prefix of complete name. Signed-off-by: Michał Narajowski <michal.narajowski@codecoup.pl> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/hci_request.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c
index c8135680c43e..fd6406df8a07 100644
--- a/net/bluetooth/hci_request.c
+++ b/net/bluetooth/hci_request.c
@@ -973,25 +973,48 @@ void __hci_req_enable_advertising(struct hci_request *req)
static u8 append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len)
{
- size_t name_len;
+ size_t complete_len;
+ size_t short_len;
int max_len;
max_len = HCI_MAX_AD_LENGTH - ad_len - 2;
- name_len = strlen(hdev->dev_name);
- if (name_len > 0 && max_len > 0) {
+ complete_len = strlen(hdev->dev_name);
+ short_len = strlen(hdev->short_name);
- if (name_len > max_len) {
- name_len = max_len;
- ptr[1] = EIR_NAME_SHORT;
- } else
- ptr[1] = EIR_NAME_COMPLETE;
+ /* no space left for name */
+ if (max_len < 1)
+ return ad_len;
- ptr[0] = name_len + 1;
+ /* no name set */
+ if (!complete_len)
+ return ad_len;
- memcpy(ptr + 2, hdev->dev_name, name_len);
+ /* complete name fits and is eq to max short name len or smaller */
+ if (complete_len <= max_len &&
+ complete_len <= HCI_MAX_SHORT_NAME_LENGTH) {
+ ptr[0] = complete_len + 1;
+ ptr[1] = EIR_NAME_COMPLETE;
+ memcpy(ptr + 2, hdev->dev_name, complete_len);
- ad_len += (name_len + 2);
- ptr += (name_len + 2);
+ return ad_len + complete_len + 2;
+ }
+
+ /* short name set and fits */
+ if (short_len && short_len <= max_len) {
+ ptr[0] = short_len + 1;
+ ptr[1] = EIR_NAME_SHORT;
+ memcpy(ptr + 2, hdev->short_name, short_len);
+
+ return ad_len + short_len + 2;
+ }
+
+ /* no short name set so shorten complete name */
+ if (!short_len) {
+ ptr[0] = max_len + 1;
+ ptr[1] = EIR_NAME_SHORT;
+ memcpy(ptr + 2, hdev->dev_name, max_len);
+
+ return ad_len + max_len + 2;
}
return ad_len;