diff options
author | Johan Hedberg <johan.hedberg@intel.com> | 2011-12-14 17:47:38 -0500 |
---|---|---|
committer | Gustavo F. Padovan <padovan@profusion.mobi> | 2011-12-18 14:38:08 -0500 |
commit | ef5803729c2323204f7372617ad97e55e94153b9 (patch) | |
tree | 0dc8f6dbccc05a56cf8f553d23a242ad6db798f7 /net/bluetooth/mgmt.c | |
parent | 14c0b60829751135346d71e7d11649c4f72dc9af (diff) |
Bluetooth: Move EIR and CoD update functions to a better position
Due to the upcoming addition of a service cache timer the functions to
update the EIR and CoD need to be higher up in mgmt.c in order to avoid
unnecessary forward-declarations. This patch simply moves code around
without any other changes in order to make subsequent patches more
readable.
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r-- | net/bluetooth/mgmt.c | 346 |
1 files changed, 173 insertions, 173 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c index 559b938f504c..cc4ea392ac6a 100644 --- a/net/bluetooth/mgmt.c +++ b/net/bluetooth/mgmt.c | |||
@@ -299,6 +299,179 @@ static u32 get_current_settings(struct hci_dev *hdev) | |||
299 | return settings; | 299 | return settings; |
300 | } | 300 | } |
301 | 301 | ||
302 | #define EIR_FLAGS 0x01 /* flags */ | ||
303 | #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ | ||
304 | #define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ | ||
305 | #define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ | ||
306 | #define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ | ||
307 | #define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ | ||
308 | #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ | ||
309 | #define EIR_NAME_SHORT 0x08 /* shortened local name */ | ||
310 | #define EIR_NAME_COMPLETE 0x09 /* complete local name */ | ||
311 | #define EIR_TX_POWER 0x0A /* transmit power level */ | ||
312 | #define EIR_DEVICE_ID 0x10 /* device ID */ | ||
313 | |||
314 | #define PNP_INFO_SVCLASS_ID 0x1200 | ||
315 | |||
316 | static u8 bluetooth_base_uuid[] = { | ||
317 | 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, | ||
318 | 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
319 | }; | ||
320 | |||
321 | static u16 get_uuid16(u8 *uuid128) | ||
322 | { | ||
323 | u32 val; | ||
324 | int i; | ||
325 | |||
326 | for (i = 0; i < 12; i++) { | ||
327 | if (bluetooth_base_uuid[i] != uuid128[i]) | ||
328 | return 0; | ||
329 | } | ||
330 | |||
331 | memcpy(&val, &uuid128[12], 4); | ||
332 | |||
333 | val = le32_to_cpu(val); | ||
334 | if (val > 0xffff) | ||
335 | return 0; | ||
336 | |||
337 | return (u16) val; | ||
338 | } | ||
339 | |||
340 | static void create_eir(struct hci_dev *hdev, u8 *data) | ||
341 | { | ||
342 | u8 *ptr = data; | ||
343 | u16 eir_len = 0; | ||
344 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | ||
345 | int i, truncated = 0; | ||
346 | struct bt_uuid *uuid; | ||
347 | size_t name_len; | ||
348 | |||
349 | name_len = strlen(hdev->dev_name); | ||
350 | |||
351 | if (name_len > 0) { | ||
352 | /* EIR Data type */ | ||
353 | if (name_len > 48) { | ||
354 | name_len = 48; | ||
355 | ptr[1] = EIR_NAME_SHORT; | ||
356 | } else | ||
357 | ptr[1] = EIR_NAME_COMPLETE; | ||
358 | |||
359 | /* EIR Data length */ | ||
360 | ptr[0] = name_len + 1; | ||
361 | |||
362 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
363 | |||
364 | eir_len += (name_len + 2); | ||
365 | ptr += (name_len + 2); | ||
366 | } | ||
367 | |||
368 | memset(uuid16_list, 0, sizeof(uuid16_list)); | ||
369 | |||
370 | /* Group all UUID16 types */ | ||
371 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
372 | u16 uuid16; | ||
373 | |||
374 | uuid16 = get_uuid16(uuid->uuid); | ||
375 | if (uuid16 == 0) | ||
376 | return; | ||
377 | |||
378 | if (uuid16 < 0x1100) | ||
379 | continue; | ||
380 | |||
381 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
382 | continue; | ||
383 | |||
384 | /* Stop if not enough space to put next UUID */ | ||
385 | if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { | ||
386 | truncated = 1; | ||
387 | break; | ||
388 | } | ||
389 | |||
390 | /* Check for duplicates */ | ||
391 | for (i = 0; uuid16_list[i] != 0; i++) | ||
392 | if (uuid16_list[i] == uuid16) | ||
393 | break; | ||
394 | |||
395 | if (uuid16_list[i] == 0) { | ||
396 | uuid16_list[i] = uuid16; | ||
397 | eir_len += sizeof(u16); | ||
398 | } | ||
399 | } | ||
400 | |||
401 | if (uuid16_list[0] != 0) { | ||
402 | u8 *length = ptr; | ||
403 | |||
404 | /* EIR Data type */ | ||
405 | ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; | ||
406 | |||
407 | ptr += 2; | ||
408 | eir_len += 2; | ||
409 | |||
410 | for (i = 0; uuid16_list[i] != 0; i++) { | ||
411 | *ptr++ = (uuid16_list[i] & 0x00ff); | ||
412 | *ptr++ = (uuid16_list[i] & 0xff00) >> 8; | ||
413 | } | ||
414 | |||
415 | /* EIR Data length */ | ||
416 | *length = (i * sizeof(u16)) + 1; | ||
417 | } | ||
418 | } | ||
419 | |||
420 | static int update_eir(struct hci_dev *hdev) | ||
421 | { | ||
422 | struct hci_cp_write_eir cp; | ||
423 | |||
424 | if (!(hdev->features[6] & LMP_EXT_INQ)) | ||
425 | return 0; | ||
426 | |||
427 | if (hdev->ssp_mode == 0) | ||
428 | return 0; | ||
429 | |||
430 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
431 | return 0; | ||
432 | |||
433 | memset(&cp, 0, sizeof(cp)); | ||
434 | |||
435 | create_eir(hdev, cp.data); | ||
436 | |||
437 | if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) | ||
438 | return 0; | ||
439 | |||
440 | memcpy(hdev->eir, cp.data, sizeof(cp.data)); | ||
441 | |||
442 | return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
443 | } | ||
444 | |||
445 | static u8 get_service_classes(struct hci_dev *hdev) | ||
446 | { | ||
447 | struct bt_uuid *uuid; | ||
448 | u8 val = 0; | ||
449 | |||
450 | list_for_each_entry(uuid, &hdev->uuids, list) | ||
451 | val |= uuid->svc_hint; | ||
452 | |||
453 | return val; | ||
454 | } | ||
455 | |||
456 | static int update_class(struct hci_dev *hdev) | ||
457 | { | ||
458 | u8 cod[3]; | ||
459 | |||
460 | BT_DBG("%s", hdev->name); | ||
461 | |||
462 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
463 | return 0; | ||
464 | |||
465 | cod[0] = hdev->minor_class; | ||
466 | cod[1] = hdev->major_class; | ||
467 | cod[2] = get_service_classes(hdev); | ||
468 | |||
469 | if (memcmp(cod, hdev->dev_class, 3) == 0) | ||
470 | return 0; | ||
471 | |||
472 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | ||
473 | } | ||
474 | |||
302 | static int read_controller_info(struct sock *sk, u16 index) | 475 | static int read_controller_info(struct sock *sk, u16 index) |
303 | { | 476 | { |
304 | struct mgmt_rp_read_info rp; | 477 | struct mgmt_rp_read_info rp; |
@@ -681,179 +854,6 @@ failed: | |||
681 | return err; | 854 | return err; |
682 | } | 855 | } |
683 | 856 | ||
684 | #define EIR_FLAGS 0x01 /* flags */ | ||
685 | #define EIR_UUID16_SOME 0x02 /* 16-bit UUID, more available */ | ||
686 | #define EIR_UUID16_ALL 0x03 /* 16-bit UUID, all listed */ | ||
687 | #define EIR_UUID32_SOME 0x04 /* 32-bit UUID, more available */ | ||
688 | #define EIR_UUID32_ALL 0x05 /* 32-bit UUID, all listed */ | ||
689 | #define EIR_UUID128_SOME 0x06 /* 128-bit UUID, more available */ | ||
690 | #define EIR_UUID128_ALL 0x07 /* 128-bit UUID, all listed */ | ||
691 | #define EIR_NAME_SHORT 0x08 /* shortened local name */ | ||
692 | #define EIR_NAME_COMPLETE 0x09 /* complete local name */ | ||
693 | #define EIR_TX_POWER 0x0A /* transmit power level */ | ||
694 | #define EIR_DEVICE_ID 0x10 /* device ID */ | ||
695 | |||
696 | #define PNP_INFO_SVCLASS_ID 0x1200 | ||
697 | |||
698 | static u8 bluetooth_base_uuid[] = { | ||
699 | 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00, 0x00, 0x80, | ||
700 | 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
701 | }; | ||
702 | |||
703 | static u16 get_uuid16(u8 *uuid128) | ||
704 | { | ||
705 | u32 val; | ||
706 | int i; | ||
707 | |||
708 | for (i = 0; i < 12; i++) { | ||
709 | if (bluetooth_base_uuid[i] != uuid128[i]) | ||
710 | return 0; | ||
711 | } | ||
712 | |||
713 | memcpy(&val, &uuid128[12], 4); | ||
714 | |||
715 | val = le32_to_cpu(val); | ||
716 | if (val > 0xffff) | ||
717 | return 0; | ||
718 | |||
719 | return (u16) val; | ||
720 | } | ||
721 | |||
722 | static void create_eir(struct hci_dev *hdev, u8 *data) | ||
723 | { | ||
724 | u8 *ptr = data; | ||
725 | u16 eir_len = 0; | ||
726 | u16 uuid16_list[HCI_MAX_EIR_LENGTH / sizeof(u16)]; | ||
727 | int i, truncated = 0; | ||
728 | struct bt_uuid *uuid; | ||
729 | size_t name_len; | ||
730 | |||
731 | name_len = strlen(hdev->dev_name); | ||
732 | |||
733 | if (name_len > 0) { | ||
734 | /* EIR Data type */ | ||
735 | if (name_len > 48) { | ||
736 | name_len = 48; | ||
737 | ptr[1] = EIR_NAME_SHORT; | ||
738 | } else | ||
739 | ptr[1] = EIR_NAME_COMPLETE; | ||
740 | |||
741 | /* EIR Data length */ | ||
742 | ptr[0] = name_len + 1; | ||
743 | |||
744 | memcpy(ptr + 2, hdev->dev_name, name_len); | ||
745 | |||
746 | eir_len += (name_len + 2); | ||
747 | ptr += (name_len + 2); | ||
748 | } | ||
749 | |||
750 | memset(uuid16_list, 0, sizeof(uuid16_list)); | ||
751 | |||
752 | /* Group all UUID16 types */ | ||
753 | list_for_each_entry(uuid, &hdev->uuids, list) { | ||
754 | u16 uuid16; | ||
755 | |||
756 | uuid16 = get_uuid16(uuid->uuid); | ||
757 | if (uuid16 == 0) | ||
758 | return; | ||
759 | |||
760 | if (uuid16 < 0x1100) | ||
761 | continue; | ||
762 | |||
763 | if (uuid16 == PNP_INFO_SVCLASS_ID) | ||
764 | continue; | ||
765 | |||
766 | /* Stop if not enough space to put next UUID */ | ||
767 | if (eir_len + 2 + sizeof(u16) > HCI_MAX_EIR_LENGTH) { | ||
768 | truncated = 1; | ||
769 | break; | ||
770 | } | ||
771 | |||
772 | /* Check for duplicates */ | ||
773 | for (i = 0; uuid16_list[i] != 0; i++) | ||
774 | if (uuid16_list[i] == uuid16) | ||
775 | break; | ||
776 | |||
777 | if (uuid16_list[i] == 0) { | ||
778 | uuid16_list[i] = uuid16; | ||
779 | eir_len += sizeof(u16); | ||
780 | } | ||
781 | } | ||
782 | |||
783 | if (uuid16_list[0] != 0) { | ||
784 | u8 *length = ptr; | ||
785 | |||
786 | /* EIR Data type */ | ||
787 | ptr[1] = truncated ? EIR_UUID16_SOME : EIR_UUID16_ALL; | ||
788 | |||
789 | ptr += 2; | ||
790 | eir_len += 2; | ||
791 | |||
792 | for (i = 0; uuid16_list[i] != 0; i++) { | ||
793 | *ptr++ = (uuid16_list[i] & 0x00ff); | ||
794 | *ptr++ = (uuid16_list[i] & 0xff00) >> 8; | ||
795 | } | ||
796 | |||
797 | /* EIR Data length */ | ||
798 | *length = (i * sizeof(u16)) + 1; | ||
799 | } | ||
800 | } | ||
801 | |||
802 | static int update_eir(struct hci_dev *hdev) | ||
803 | { | ||
804 | struct hci_cp_write_eir cp; | ||
805 | |||
806 | if (!(hdev->features[6] & LMP_EXT_INQ)) | ||
807 | return 0; | ||
808 | |||
809 | if (hdev->ssp_mode == 0) | ||
810 | return 0; | ||
811 | |||
812 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
813 | return 0; | ||
814 | |||
815 | memset(&cp, 0, sizeof(cp)); | ||
816 | |||
817 | create_eir(hdev, cp.data); | ||
818 | |||
819 | if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0) | ||
820 | return 0; | ||
821 | |||
822 | memcpy(hdev->eir, cp.data, sizeof(cp.data)); | ||
823 | |||
824 | return hci_send_cmd(hdev, HCI_OP_WRITE_EIR, sizeof(cp), &cp); | ||
825 | } | ||
826 | |||
827 | static u8 get_service_classes(struct hci_dev *hdev) | ||
828 | { | ||
829 | struct bt_uuid *uuid; | ||
830 | u8 val = 0; | ||
831 | |||
832 | list_for_each_entry(uuid, &hdev->uuids, list) | ||
833 | val |= uuid->svc_hint; | ||
834 | |||
835 | return val; | ||
836 | } | ||
837 | |||
838 | static int update_class(struct hci_dev *hdev) | ||
839 | { | ||
840 | u8 cod[3]; | ||
841 | |||
842 | BT_DBG("%s", hdev->name); | ||
843 | |||
844 | if (test_bit(HCI_SERVICE_CACHE, &hdev->flags)) | ||
845 | return 0; | ||
846 | |||
847 | cod[0] = hdev->minor_class; | ||
848 | cod[1] = hdev->major_class; | ||
849 | cod[2] = get_service_classes(hdev); | ||
850 | |||
851 | if (memcmp(cod, hdev->dev_class, 3) == 0) | ||
852 | return 0; | ||
853 | |||
854 | return hci_send_cmd(hdev, HCI_OP_WRITE_CLASS_OF_DEV, sizeof(cod), cod); | ||
855 | } | ||
856 | |||
857 | static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) | 857 | static int add_uuid(struct sock *sk, u16 index, unsigned char *data, u16 len) |
858 | { | 858 | { |
859 | struct mgmt_cp_add_uuid *cp; | 859 | struct mgmt_cp_add_uuid *cp; |