1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2021 Intel Corporation 6 */ 7 8 #include <net/bluetooth/bluetooth.h> 9 #include <net/bluetooth/hci_core.h> 10 #include <net/bluetooth/mgmt.h> 11 12 #include "eir.h" 13 14 #define PNP_INFO_SVCLASS_ID 0x1200 15 16 u8 eir_append_local_name(struct hci_dev *hdev, u8 *ptr, u8 ad_len) 17 { 18 size_t short_len; 19 size_t complete_len; 20 21 /* no space left for name (+ NULL + type + len) */ 22 if ((HCI_MAX_AD_LENGTH - ad_len) < HCI_MAX_SHORT_NAME_LENGTH + 3) 23 return ad_len; 24 25 /* use complete name if present and fits */ 26 complete_len = strlen(hdev->dev_name); 27 if (complete_len && complete_len <= HCI_MAX_SHORT_NAME_LENGTH) 28 return eir_append_data(ptr, ad_len, EIR_NAME_COMPLETE, 29 hdev->dev_name, complete_len + 1); 30 31 /* use short name if present */ 32 short_len = strlen(hdev->short_name); 33 if (short_len) 34 return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, 35 hdev->short_name, short_len + 1); 36 37 /* use shortened full name if present, we already know that name 38 * is longer then HCI_MAX_SHORT_NAME_LENGTH 39 */ 40 if (complete_len) { 41 u8 name[HCI_MAX_SHORT_NAME_LENGTH + 1]; 42 43 memcpy(name, hdev->dev_name, HCI_MAX_SHORT_NAME_LENGTH); 44 name[HCI_MAX_SHORT_NAME_LENGTH] = '\0'; 45 46 return eir_append_data(ptr, ad_len, EIR_NAME_SHORT, name, 47 sizeof(name)); 48 } 49 50 return ad_len; 51 } 52 53 u8 eir_append_appearance(struct hci_dev *hdev, u8 *ptr, u8 ad_len) 54 { 55 return eir_append_le16(ptr, ad_len, EIR_APPEARANCE, hdev->appearance); 56 } 57 58 static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) 59 { 60 u8 *ptr = data, *uuids_start = NULL; 61 struct bt_uuid *uuid; 62 63 if (len < 4) 64 return ptr; 65 66 list_for_each_entry(uuid, &hdev->uuids, list) { 67 u16 uuid16; 68 69 if (uuid->size != 16) 70 continue; 71 72 uuid16 = get_unaligned_le16(&uuid->uuid[12]); 73 if (uuid16 < 0x1100) 74 continue; 75 76 if (uuid16 == PNP_INFO_SVCLASS_ID) 77 continue; 78 79 if (!uuids_start) { 80 uuids_start = ptr; 81 uuids_start[0] = 1; 82 uuids_start[1] = EIR_UUID16_ALL; 83 ptr += 2; 84 } 85 86 /* Stop if not enough space to put next UUID */ 87 if ((ptr - data) + sizeof(u16) > len) { 88 uuids_start[1] = EIR_UUID16_SOME; 89 break; 90 } 91 92 *ptr++ = (uuid16 & 0x00ff); 93 *ptr++ = (uuid16 & 0xff00) >> 8; 94 uuids_start[0] += sizeof(uuid16); 95 } 96 97 return ptr; 98 } 99 100 static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) 101 { 102 u8 *ptr = data, *uuids_start = NULL; 103 struct bt_uuid *uuid; 104 105 if (len < 6) 106 return ptr; 107 108 list_for_each_entry(uuid, &hdev->uuids, list) { 109 if (uuid->size != 32) 110 continue; 111 112 if (!uuids_start) { 113 uuids_start = ptr; 114 uuids_start[0] = 1; 115 uuids_start[1] = EIR_UUID32_ALL; 116 ptr += 2; 117 } 118 119 /* Stop if not enough space to put next UUID */ 120 if ((ptr - data) + sizeof(u32) > len) { 121 uuids_start[1] = EIR_UUID32_SOME; 122 break; 123 } 124 125 memcpy(ptr, &uuid->uuid[12], sizeof(u32)); 126 ptr += sizeof(u32); 127 uuids_start[0] += sizeof(u32); 128 } 129 130 return ptr; 131 } 132 133 static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) 134 { 135 u8 *ptr = data, *uuids_start = NULL; 136 struct bt_uuid *uuid; 137 138 if (len < 18) 139 return ptr; 140 141 list_for_each_entry(uuid, &hdev->uuids, list) { 142 if (uuid->size != 128) 143 continue; 144 145 if (!uuids_start) { 146 uuids_start = ptr; 147 uuids_start[0] = 1; 148 uuids_start[1] = EIR_UUID128_ALL; 149 ptr += 2; 150 } 151 152 /* Stop if not enough space to put next UUID */ 153 if ((ptr - data) + 16 > len) { 154 uuids_start[1] = EIR_UUID128_SOME; 155 break; 156 } 157 158 memcpy(ptr, uuid->uuid, 16); 159 ptr += 16; 160 uuids_start[0] += 16; 161 } 162 163 return ptr; 164 } 165 166 void eir_create(struct hci_dev *hdev, u8 *data) 167 { 168 u8 *ptr = data; 169 size_t name_len; 170 171 name_len = strlen(hdev->dev_name); 172 173 if (name_len > 0) { 174 /* EIR Data type */ 175 if (name_len > 48) { 176 name_len = 48; 177 ptr[1] = EIR_NAME_SHORT; 178 } else { 179 ptr[1] = EIR_NAME_COMPLETE; 180 } 181 182 /* EIR Data length */ 183 ptr[0] = name_len + 1; 184 185 memcpy(ptr + 2, hdev->dev_name, name_len); 186 187 ptr += (name_len + 2); 188 } 189 190 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) { 191 ptr[0] = 2; 192 ptr[1] = EIR_TX_POWER; 193 ptr[2] = (u8)hdev->inq_tx_power; 194 195 ptr += 3; 196 } 197 198 if (hdev->devid_source > 0) { 199 ptr[0] = 9; 200 ptr[1] = EIR_DEVICE_ID; 201 202 put_unaligned_le16(hdev->devid_source, ptr + 2); 203 put_unaligned_le16(hdev->devid_vendor, ptr + 4); 204 put_unaligned_le16(hdev->devid_product, ptr + 6); 205 put_unaligned_le16(hdev->devid_version, ptr + 8); 206 207 ptr += 10; 208 } 209 210 ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); 211 ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); 212 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); 213 } 214 215 u8 eir_create_adv_data(struct hci_dev *hdev, u8 instance, u8 *ptr) 216 { 217 struct adv_info *adv = NULL; 218 u8 ad_len = 0, flags = 0; 219 u32 instance_flags; 220 221 /* Return 0 when the current instance identifier is invalid. */ 222 if (instance) { 223 adv = hci_find_adv_instance(hdev, instance); 224 if (!adv) 225 return 0; 226 } 227 228 instance_flags = hci_adv_instance_flags(hdev, instance); 229 230 /* If instance already has the flags set skip adding it once 231 * again. 232 */ 233 if (adv && eir_get_data(adv->adv_data, adv->adv_data_len, EIR_FLAGS, 234 NULL)) 235 goto skip_flags; 236 237 /* The Add Advertising command allows userspace to set both the general 238 * and limited discoverable flags. 239 */ 240 if (instance_flags & MGMT_ADV_FLAG_DISCOV) 241 flags |= LE_AD_GENERAL; 242 243 if (instance_flags & MGMT_ADV_FLAG_LIMITED_DISCOV) 244 flags |= LE_AD_LIMITED; 245 246 if (!hci_dev_test_flag(hdev, HCI_BREDR_ENABLED)) 247 flags |= LE_AD_NO_BREDR; 248 249 if (flags || (instance_flags & MGMT_ADV_FLAG_MANAGED_FLAGS)) { 250 /* If a discovery flag wasn't provided, simply use the global 251 * settings. 252 */ 253 if (!flags) 254 flags |= mgmt_get_adv_discov_flags(hdev); 255 256 /* If flags would still be empty, then there is no need to 257 * include the "Flags" AD field". 258 */ 259 if (flags) { 260 ptr[0] = 0x02; 261 ptr[1] = EIR_FLAGS; 262 ptr[2] = flags; 263 264 ad_len += 3; 265 ptr += 3; 266 } 267 } 268 269 skip_flags: 270 if (adv) { 271 memcpy(ptr, adv->adv_data, adv->adv_data_len); 272 ad_len += adv->adv_data_len; 273 ptr += adv->adv_data_len; 274 } 275 276 if (instance_flags & MGMT_ADV_FLAG_TX_POWER) { 277 s8 adv_tx_power; 278 279 if (ext_adv_capable(hdev)) { 280 if (adv) 281 adv_tx_power = adv->tx_power; 282 else 283 adv_tx_power = hdev->adv_tx_power; 284 } else { 285 adv_tx_power = hdev->adv_tx_power; 286 } 287 288 /* Provide Tx Power only if we can provide a valid value for it */ 289 if (adv_tx_power != HCI_TX_POWER_INVALID) { 290 ptr[0] = 0x02; 291 ptr[1] = EIR_TX_POWER; 292 ptr[2] = (u8)adv_tx_power; 293 294 ad_len += 3; 295 ptr += 3; 296 } 297 } 298 299 return ad_len; 300 } 301 302 static u8 create_default_scan_rsp(struct hci_dev *hdev, u8 *ptr) 303 { 304 u8 scan_rsp_len = 0; 305 306 if (hdev->appearance) 307 scan_rsp_len = eir_append_appearance(hdev, ptr, scan_rsp_len); 308 309 return eir_append_local_name(hdev, ptr, scan_rsp_len); 310 } 311 312 u8 eir_create_scan_rsp(struct hci_dev *hdev, u8 instance, u8 *ptr) 313 { 314 struct adv_info *adv; 315 u8 scan_rsp_len = 0; 316 317 if (!instance) 318 return create_default_scan_rsp(hdev, ptr); 319 320 adv = hci_find_adv_instance(hdev, instance); 321 if (!adv) 322 return 0; 323 324 if ((adv->flags & MGMT_ADV_FLAG_APPEARANCE) && hdev->appearance) 325 scan_rsp_len = eir_append_appearance(hdev, ptr, scan_rsp_len); 326 327 memcpy(&ptr[scan_rsp_len], adv->scan_rsp_data, adv->scan_rsp_len); 328 329 scan_rsp_len += adv->scan_rsp_len; 330 331 if (adv->flags & MGMT_ADV_FLAG_LOCAL_NAME) 332 scan_rsp_len = eir_append_local_name(hdev, ptr, scan_rsp_len); 333 334 return scan_rsp_len; 335 } 336