diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/bluetooth/mgmt.c | 78 |
1 files changed, 43 insertions, 35 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 5e18d5a451f4..497928d2b257 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -435,11 +435,51 @@ static u32 get_current_settings(struct hci_dev *hdev) | |||
435 | 435 | ||
436 | #define PNP_INFO_SVCLASS_ID 0x1200 | 436 | #define PNP_INFO_SVCLASS_ID 0x1200 |
437 | 437 | ||
438 | static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len) | ||
439 | { | ||
440 | u8 *ptr = data, *uuids_start = NULL; | ||
441 | struct bt_uuid *uuid; | ||
442 | |||
443 | if (len < 4) | ||
444 | return ptr; | ||
445 | |||
446 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
447 | u16 uuid16; | ||
448 | |||
449 | if (uuid->size != 16) | ||
450 | continue; | ||
451 | |||
452 | uuid16 = get_unaligned_le16(&uuid->uuid[12]); | ||
453 | if (uuid16 < 0x1100) | ||
454 | continue; | ||
455 | |||
456 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
457 | continue; | ||
458 | |||
459 | if (!uuids_start) { | ||
460 | uuids_start = ptr; | ||
461 | uuids_start[0] = 1; | ||
462 | uuids_start[1] = EIR_UUID16_ALL; | ||
463 | ptr += 2; | ||
464 | } | ||
465 | |||
466 | /* Stop if not enough space to put next UUID */ | ||
467 | if ((ptr - data) + sizeof(u16) > len) { | ||
468 | uuids_start[1] = EIR_UUID16_SOME; | ||
469 | break; | ||
470 | } | ||
471 | |||
472 | *ptr++ = (uuid16 & 0x00ff); | ||
473 | *ptr++ = (uuid16 & 0xff00) >> 8; | ||
474 | uuids_start[0] += sizeof(uuid16); | ||
475 | } | ||
476 | |||
477 | return ptr; | ||
478 | } | ||
479 | |||
438 | static void create_eir(struct hci_dev *hdev, u8 *data) | 480 | static void create_eir(struct hci_dev *hdev, u8 *data) |
439 | { | 481 | { |
440 | u8 *ptr = data; | 482 | u8 *ptr = data; |
441 | u8 *uuids_start; | ||
442 | struct bt_uuid *uuid; | ||
443 | size_t name_len; | 483 | size_t name_len; |
444 | 484 | ||
445 | name_len = strlen(hdev->dev_name); | 485 | name_len = strlen(hdev->dev_name); |
@@ -480,39 +520,7 @@ static void create_eir(struct hci_dev *hdev, u8 *data) | |||
480 | ptr += 10; | 520 | ptr += 10; |
481 | } | 521 | } |
482 | 522 | ||
483 | uuids_start = NULL; | 523 | ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data)); |
484 | |||
485 | /* Group all UUID16 types */ | ||
486 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
487 | u16 uuid16; | ||
488 | |||
489 | if (uuid->size != 16) | ||
490 | continue; | ||
491 | |||
492 | uuid16 = get_unaligned_le16(&uuid->uuid[12]); | ||
493 | if (uuid16 < 0x1100) | ||
494 | continue; | ||
495 | |||
496 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
497 | continue; | ||
498 | |||
499 | if (!uuids_start) { | ||
500 | uuids_start = ptr; | ||
501 | uuids_start[0] = 1; | ||
502 | uuids_start[1] = EIR_UUID16_ALL; | ||
503 | ptr += 2; | ||
504 | } | ||
505 | |||
506 | /* Stop if not enough space to put next UUID */ | ||
507 | if ((ptr - data) + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { | ||
508 | uuids_start[1] = EIR_UUID16_SOME; | ||
509 | break; | ||
510 | } | ||
511 | |||
512 | *ptr++ = (uuid16 & 0x00ff); | ||
513 | *ptr++ = (uuid16 & 0xff00) >> 8; | ||
514 | uuids_start[0] += sizeof(uuid16); | ||
515 | } | ||
516 | } | 524 | } |
517 | 525 | ||
518 | static int update_eir(struct hci_dev *hdev) | 526 | static int update_eir(struct hci_dev *hdev) |