aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/mgmt.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2015-11-25 09:15:42 -0500
committerMarcel Holtmann <marcel@holtmann.org>2015-12-09 18:51:48 -0500
commitb1a8917c9bcbf42113dfacb6492228e094c96862 (patch)
tree30fbfaacbca3bc8775596c2107fa76cbe0cb8827 /net/bluetooth/mgmt.c
parent00cf5040b39638588cd10ae4ffcc76a1be6ecf2c (diff)
Bluetooth: Move EIR update to hci_request.c
We'll soon need to update the EIR both from hci_request.c and mgmt.c so move update_eir() as a more generic request helper to hci_request.c. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/mgmt.c')
-rw-r--r--net/bluetooth/mgmt.c203
1 files changed, 8 insertions, 195 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 001a29a320e6..fa5dc67a800a 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -719,116 +719,6 @@ static u32 get_current_settings(struct hci_dev *hdev)
719 return settings; 719 return settings;
720} 720}
721 721
722#define PNP_INFO_SVCLASS_ID 0x1200
723
724static u8 *create_uuid16_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
725{
726 u8 *ptr = data, *uuids_start = NULL;
727 struct bt_uuid *uuid;
728
729 if (len < 4)
730 return ptr;
731
732 list_for_each_entry(uuid, &hdev->uuids, list) {
733 u16 uuid16;
734
735 if (uuid->size != 16)
736 continue;
737
738 uuid16 = get_unaligned_le16(&uuid->uuid[12]);
739 if (uuid16 < 0x1100)
740 continue;
741
742 if (uuid16 == PNP_INFO_SVCLASS_ID)
743 continue;
744
745 if (!uuids_start) {
746 uuids_start = ptr;
747 uuids_start[0] = 1;
748 uuids_start[1] = EIR_UUID16_ALL;
749 ptr += 2;
750 }
751
752 /* Stop if not enough space to put next UUID */
753 if ((ptr - data) + sizeof(u16) > len) {
754 uuids_start[1] = EIR_UUID16_SOME;
755 break;
756 }
757
758 *ptr++ = (uuid16 & 0x00ff);
759 *ptr++ = (uuid16 & 0xff00) >> 8;
760 uuids_start[0] += sizeof(uuid16);
761 }
762
763 return ptr;
764}
765
766static u8 *create_uuid32_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
767{
768 u8 *ptr = data, *uuids_start = NULL;
769 struct bt_uuid *uuid;
770
771 if (len < 6)
772 return ptr;
773
774 list_for_each_entry(uuid, &hdev->uuids, list) {
775 if (uuid->size != 32)
776 continue;
777
778 if (!uuids_start) {
779 uuids_start = ptr;
780 uuids_start[0] = 1;
781 uuids_start[1] = EIR_UUID32_ALL;
782 ptr += 2;
783 }
784
785 /* Stop if not enough space to put next UUID */
786 if ((ptr - data) + sizeof(u32) > len) {
787 uuids_start[1] = EIR_UUID32_SOME;
788 break;
789 }
790
791 memcpy(ptr, &uuid->uuid[12], sizeof(u32));
792 ptr += sizeof(u32);
793 uuids_start[0] += sizeof(u32);
794 }
795
796 return ptr;
797}
798
799static u8 *create_uuid128_list(struct hci_dev *hdev, u8 *data, ptrdiff_t len)
800{
801 u8 *ptr = data, *uuids_start = NULL;
802 struct bt_uuid *uuid;
803
804 if (len < 18)
805 return ptr;
806
807 list_for_each_entry(uuid, &hdev->uuids, list) {
808 if (uuid->size != 128)
809 continue;
810
811 if (!uuids_start) {
812 uuids_start = ptr;
813 uuids_start[0] = 1;
814 uuids_start[1] = EIR_UUID128_ALL;
815 ptr += 2;
816 }
817
818 /* Stop if not enough space to put next UUID */
819 if ((ptr - data) + 16 > len) {
820 uuids_start[1] = EIR_UUID128_SOME;
821 break;
822 }
823
824 memcpy(ptr, uuid->uuid, 16);
825 ptr += 16;
826 uuids_start[0] += 16;
827 }
828
829 return ptr;
830}
831
832static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev) 722static struct mgmt_pending_cmd *pending_find(u16 opcode, struct hci_dev *hdev)
833{ 723{
834 return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev); 724 return mgmt_pending_find(HCI_CHANNEL_CONTROL, opcode, hdev);
@@ -882,83 +772,6 @@ bool mgmt_get_connectable(struct hci_dev *hdev)
882 return hci_dev_test_flag(hdev, HCI_CONNECTABLE); 772 return hci_dev_test_flag(hdev, HCI_CONNECTABLE);
883} 773}
884 774
885static void create_eir(struct hci_dev *hdev, u8 *data)
886{
887 u8 *ptr = data;
888 size_t name_len;
889
890 name_len = strlen(hdev->dev_name);
891
892 if (name_len > 0) {
893 /* EIR Data type */
894 if (name_len > 48) {
895 name_len = 48;
896 ptr[1] = EIR_NAME_SHORT;
897 } else
898 ptr[1] = EIR_NAME_COMPLETE;
899
900 /* EIR Data length */
901 ptr[0] = name_len + 1;
902
903 memcpy(ptr + 2, hdev->dev_name, name_len);
904
905 ptr += (name_len + 2);
906 }
907
908 if (hdev->inq_tx_power != HCI_TX_POWER_INVALID) {
909 ptr[0] = 2;
910 ptr[1] = EIR_TX_POWER;
911 ptr[2] = (u8) hdev->inq_tx_power;
912
913 ptr += 3;
914 }
915
916 if (hdev->devid_source > 0) {
917 ptr[0] = 9;
918 ptr[1] = EIR_DEVICE_ID;
919
920 put_unaligned_le16(hdev->devid_source, ptr + 2);
921 put_unaligned_le16(hdev->devid_vendor, ptr + 4);
922 put_unaligned_le16(hdev->devid_product, ptr + 6);
923 put_unaligned_le16(hdev->devid_version, ptr + 8);
924
925 ptr += 10;
926 }
927
928 ptr = create_uuid16_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
929 ptr = create_uuid32_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
930 ptr = create_uuid128_list(hdev, ptr, HCI_MAX_EIR_LENGTH - (ptr - data));
931}
932
933static void update_eir(struct hci_request *req)
934{
935 struct hci_dev *hdev = req->hdev;
936 struct hci_cp_write_eir cp;
937
938 if (!hdev_is_powered(hdev))
939 return;
940
941 if (!lmp_ext_inq_capable(hdev))
942 return;
943
944 if (!hci_dev_test_flag(hdev, HCI_SSP_ENABLED))
945 return;
946
947 if (hci_dev_test_flag(hdev, HCI_SERVICE_CACHE))
948 return;
949
950 memset(&cp, 0, sizeof(cp));
951
952 create_eir(hdev, cp.data);
953
954 if (memcmp(cp.data, hdev->eir, sizeof(cp.data)) == 0)
955 return;
956
957 memcpy(hdev->eir, cp.data, sizeof(cp.data));
958
959 hci_req_add(req, HCI_OP_WRITE_EIR, sizeof(cp), &cp);
960}
961
962static void service_cache_off(struct work_struct *work) 775static void service_cache_off(struct work_struct *work)
963{ 776{
964 struct hci_dev *hdev = container_of(work, struct hci_dev, 777 struct hci_dev *hdev = container_of(work, struct hci_dev,
@@ -972,7 +785,7 @@ static void service_cache_off(struct work_struct *work)
972 785
973 hci_dev_lock(hdev); 786 hci_dev_lock(hdev);
974 787
975 update_eir(&req); 788 __hci_req_update_eir(&req);
976 __hci_req_update_class(&req); 789 __hci_req_update_class(&req);
977 790
978 hci_dev_unlock(hdev); 791 hci_dev_unlock(hdev);
@@ -2074,7 +1887,7 @@ static int add_uuid(struct sock *sk, struct hci_dev *hdev, void *data, u16 len)
2074 hci_req_init(&req, hdev); 1887 hci_req_init(&req, hdev);
2075 1888
2076 __hci_req_update_class(&req); 1889 __hci_req_update_class(&req);
2077 update_eir(&req); 1890 __hci_req_update_eir(&req);
2078 1891
2079 err = hci_req_run(&req, add_uuid_complete); 1892 err = hci_req_run(&req, add_uuid_complete);
2080 if (err < 0) { 1893 if (err < 0) {
@@ -2174,7 +1987,7 @@ update_class:
2174 hci_req_init(&req, hdev); 1987 hci_req_init(&req, hdev);
2175 1988
2176 __hci_req_update_class(&req); 1989 __hci_req_update_class(&req);
2177 update_eir(&req); 1990 __hci_req_update_eir(&req);
2178 1991
2179 err = hci_req_run(&req, remove_uuid_complete); 1992 err = hci_req_run(&req, remove_uuid_complete);
2180 if (err < 0) { 1993 if (err < 0) {
@@ -2249,7 +2062,7 @@ static int set_dev_class(struct sock *sk, struct hci_dev *hdev, void *data,
2249 hci_dev_unlock(hdev); 2062 hci_dev_unlock(hdev);
2250 cancel_delayed_work_sync(&hdev->service_cache); 2063 cancel_delayed_work_sync(&hdev->service_cache);
2251 hci_dev_lock(hdev); 2064 hci_dev_lock(hdev);
2252 update_eir(&req); 2065 __hci_req_update_eir(&req);
2253 } 2066 }
2254 2067
2255 __hci_req_update_class(&req); 2068 __hci_req_update_class(&req);
@@ -3232,7 +3045,7 @@ static int set_local_name(struct sock *sk, struct hci_dev *hdev, void *data,
3232 3045
3233 if (lmp_bredr_capable(hdev)) { 3046 if (lmp_bredr_capable(hdev)) {
3234 __hci_req_update_name(&req); 3047 __hci_req_update_name(&req);
3235 update_eir(&req); 3048 __hci_req_update_eir(&req);
3236 } 3049 }
3237 3050
3238 /* The name is stored in the scan response data and so 3051 /* The name is stored in the scan response data and so
@@ -3917,7 +3730,7 @@ static int set_device_id(struct sock *sk, struct hci_dev *hdev, void *data,
3917 NULL, 0); 3730 NULL, 0);
3918 3731
3919 hci_req_init(&req, hdev); 3732 hci_req_init(&req, hdev);
3920 update_eir(&req); 3733 __hci_req_update_eir(&req);
3921 hci_req_run(&req, NULL); 3734 hci_req_run(&req, NULL);
3922 3735
3923 hci_dev_unlock(hdev); 3736 hci_dev_unlock(hdev);
@@ -6759,7 +6572,7 @@ static int powered_update_hci(struct hci_dev *hdev)
6759 __hci_req_update_scan(&req); 6572 __hci_req_update_scan(&req);
6760 __hci_req_update_class(&req); 6573 __hci_req_update_class(&req);
6761 __hci_req_update_name(&req); 6574 __hci_req_update_name(&req);
6762 update_eir(&req); 6575 __hci_req_update_eir(&req);
6763 } 6576 }
6764 6577
6765 return hci_req_run(&req, powered_complete); 6578 return hci_req_run(&req, powered_complete);
@@ -7380,7 +7193,7 @@ void mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 enable, u8 status)
7380 if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS)) 7193 if (hci_dev_test_flag(hdev, HCI_USE_DEBUG_KEYS))
7381 hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE, 7194 hci_req_add(&req, HCI_OP_WRITE_SSP_DEBUG_MODE,
7382 sizeof(enable), &enable); 7195 sizeof(enable), &enable);
7383 update_eir(&req); 7196 __hci_req_update_eir(&req);
7384 } else { 7197 } else {
7385 clear_eir(&req); 7198 clear_eir(&req);
7386 } 7199 }