aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@intel.com>2012-02-21 09:55:31 -0500
committerJohan Hedberg <johan.hedberg@intel.com>2012-02-21 13:04:39 -0500
commitbeadb2bddce5810dc668da156b4c2ca457940250 (patch)
treebd5f35de714ff980ddd9036763d4a5dce94c3d81
parentf1f0eb02213a3003ecb10b9c61694e588267b824 (diff)
Bluetooth: mgmt: Add convenience function for sending New Settings
The New Settings event needs to be sent from quite many places so it makes sense to have a convenience function for it to simplify the code. Signed-off-by: Johan Hedberg <johan.hedberg@intel.com> Acked-by: Marcel Holtmann <marcel@holtmann.org>
-rw-r--r--net/bluetooth/mgmt.c96
1 files changed, 44 insertions, 52 deletions
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 86e63a707f5a..439ec786ff8c 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -796,6 +796,42 @@ failed:
796 return err; 796 return err;
797} 797}
798 798
799static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
800 u16 data_len, struct sock *skip_sk)
801{
802 struct sk_buff *skb;
803 struct mgmt_hdr *hdr;
804
805 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
806 if (!skb)
807 return -ENOMEM;
808
809 hdr = (void *) skb_put(skb, sizeof(*hdr));
810 hdr->opcode = cpu_to_le16(event);
811 if (hdev)
812 hdr->index = cpu_to_le16(hdev->id);
813 else
814 hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
815 hdr->len = cpu_to_le16(data_len);
816
817 if (data)
818 memcpy(skb_put(skb, data_len), data, data_len);
819
820 hci_send_to_control(skb, skip_sk);
821 kfree_skb(skb);
822
823 return 0;
824}
825
826static int new_settings(struct hci_dev *hdev, struct sock *skip)
827{
828 __le32 ev;
829
830 ev = cpu_to_le32(get_current_settings(hdev));
831
832 return mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), skip);
833}
834
799static int set_discoverable(struct sock *sk, u16 index, void *data, u16 len) 835static int set_discoverable(struct sock *sk, u16 index, void *data, u16 len)
800{ 836{
801 struct mgmt_cp_set_discoverable *cp = data; 837 struct mgmt_cp_set_discoverable *cp = data;
@@ -951,38 +987,10 @@ failed:
951 return err; 987 return err;
952} 988}
953 989
954static int mgmt_event(u16 event, struct hci_dev *hdev, void *data,
955 u16 data_len, struct sock *skip_sk)
956{
957 struct sk_buff *skb;
958 struct mgmt_hdr *hdr;
959
960 skb = alloc_skb(sizeof(*hdr) + data_len, GFP_ATOMIC);
961 if (!skb)
962 return -ENOMEM;
963
964 hdr = (void *) skb_put(skb, sizeof(*hdr));
965 hdr->opcode = cpu_to_le16(event);
966 if (hdev)
967 hdr->index = cpu_to_le16(hdev->id);
968 else
969 hdr->index = cpu_to_le16(MGMT_INDEX_NONE);
970 hdr->len = cpu_to_le16(data_len);
971
972 if (data)
973 memcpy(skb_put(skb, data_len), data, data_len);
974
975 hci_send_to_control(skb, skip_sk);
976 kfree_skb(skb);
977
978 return 0;
979}
980
981static int set_pairable(struct sock *sk, u16 index, void *data, u16 len) 990static int set_pairable(struct sock *sk, u16 index, void *data, u16 len)
982{ 991{
983 struct mgmt_mode *cp = data; 992 struct mgmt_mode *cp = data;
984 struct hci_dev *hdev; 993 struct hci_dev *hdev;
985 __le32 ev;
986 int err; 994 int err;
987 995
988 BT_DBG("request for hci%u", index); 996 BT_DBG("request for hci%u", index);
@@ -1007,9 +1015,7 @@ static int set_pairable(struct sock *sk, u16 index, void *data, u16 len)
1007 if (err < 0) 1015 if (err < 0)
1008 goto failed; 1016 goto failed;
1009 1017
1010 ev = cpu_to_le32(get_current_settings(hdev)); 1018 err = new_settings(hdev, sk);
1011
1012 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), sk);
1013 1019
1014failed: 1020failed:
1015 hci_dev_unlock(hdev); 1021 hci_dev_unlock(hdev);
@@ -2902,7 +2908,6 @@ static void settings_rsp(struct pending_cmd *cmd, void *data)
2902int mgmt_powered(struct hci_dev *hdev, u8 powered) 2908int mgmt_powered(struct hci_dev *hdev, u8 powered)
2903{ 2909{
2904 struct cmd_lookup match = { NULL, hdev }; 2910 struct cmd_lookup match = { NULL, hdev };
2905 __le32 ev;
2906 int err; 2911 int err;
2907 2912
2908 if (!test_bit(HCI_MGMT, &hdev->dev_flags)) 2913 if (!test_bit(HCI_MGMT, &hdev->dev_flags))
@@ -2925,10 +2930,7 @@ int mgmt_powered(struct hci_dev *hdev, u8 powered)
2925 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status); 2930 mgmt_pending_foreach(0, hdev, cmd_status_rsp, &status);
2926 } 2931 }
2927 2932
2928 ev = cpu_to_le32(get_current_settings(hdev)); 2933 err = new_settings(hdev, match.sk);
2929
2930 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
2931 match.sk);
2932 2934
2933 if (match.sk) 2935 if (match.sk)
2934 sock_put(match.sk); 2936 sock_put(match.sk);
@@ -2952,11 +2954,8 @@ int mgmt_discoverable(struct hci_dev *hdev, u8 discoverable)
2952 changed = true; 2954 changed = true;
2953 } 2955 }
2954 2956
2955 if (changed) { 2957 if (changed)
2956 __le32 ev = cpu_to_le32(get_current_settings(hdev)); 2958 err = new_settings(hdev, match.sk);
2957 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
2958 match.sk);
2959 }
2960 2959
2961 if (match.sk) 2960 if (match.sk)
2962 sock_put(match.sk); 2961 sock_put(match.sk);
@@ -2981,11 +2980,8 @@ int mgmt_connectable(struct hci_dev *hdev, u8 connectable)
2981 changed = true; 2980 changed = true;
2982 } 2981 }
2983 2982
2984 if (changed) { 2983 if (changed)
2985 __le32 ev = cpu_to_le32(get_current_settings(hdev)); 2984 err = new_settings(hdev, match.sk);
2986 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev),
2987 match.sk);
2988 }
2989 2985
2990 if (match.sk) 2986 if (match.sk)
2991 sock_put(match.sk); 2987 sock_put(match.sk);
@@ -3320,7 +3316,6 @@ int mgmt_auth_failed(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 link_type,
3320int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status) 3316int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3321{ 3317{
3322 struct cmd_lookup match = { NULL, hdev }; 3318 struct cmd_lookup match = { NULL, hdev };
3323 __le32 ev;
3324 int err; 3319 int err;
3325 3320
3326 if (status) { 3321 if (status) {
@@ -3333,8 +3328,7 @@ int mgmt_auth_enable_complete(struct hci_dev *hdev, u8 status)
3333 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp, 3328 mgmt_pending_foreach(MGMT_OP_SET_LINK_SECURITY, hdev, settings_rsp,
3334 &match); 3329 &match);
3335 3330
3336 ev = cpu_to_le32(get_current_settings(hdev)); 3331 err = new_settings(hdev, match.sk);
3337 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3338 3332
3339 if (match.sk) 3333 if (match.sk)
3340 sock_put(match.sk); 3334 sock_put(match.sk);
@@ -3357,7 +3351,6 @@ static int clear_eir(struct hci_dev *hdev)
3357int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 status) 3351int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 status)
3358{ 3352{
3359 struct cmd_lookup match = { NULL, hdev }; 3353 struct cmd_lookup match = { NULL, hdev };
3360 __le32 ev;
3361 int err; 3354 int err;
3362 3355
3363 if (status) { 3356 if (status) {
@@ -3369,8 +3362,7 @@ int mgmt_ssp_enable_complete(struct hci_dev *hdev, u8 status)
3369 3362
3370 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match); 3363 mgmt_pending_foreach(MGMT_OP_SET_SSP, hdev, settings_rsp, &match);
3371 3364
3372 ev = cpu_to_le32(get_current_settings(hdev)); 3365 err = new_settings(hdev, match.sk);
3373 err = mgmt_event(MGMT_EV_NEW_SETTINGS, hdev, &ev, sizeof(ev), match.sk);
3374 3366
3375 if (match.sk) { 3367 if (match.sk) {
3376 sock_put(match.sk); 3368 sock_put(match.sk);