diff options
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r-- | net/bluetooth/hci_event.c | 75 |
1 files changed, 63 insertions, 12 deletions
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index d4d2dcc40fc7..9af181a61650 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -110,6 +110,25 @@ static void hci_cc_role_discovery(struct hci_dev *hdev, struct sk_buff *skb) | |||
110 | hci_dev_unlock(hdev); | 110 | hci_dev_unlock(hdev); |
111 | } | 111 | } |
112 | 112 | ||
113 | static void hci_cc_read_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | ||
114 | { | ||
115 | struct hci_rp_read_link_policy *rp = (void *) skb->data; | ||
116 | struct hci_conn *conn; | ||
117 | |||
118 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
119 | |||
120 | if (rp->status) | ||
121 | return; | ||
122 | |||
123 | hci_dev_lock(hdev); | ||
124 | |||
125 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); | ||
126 | if (conn) | ||
127 | conn->link_policy = __le16_to_cpu(rp->policy); | ||
128 | |||
129 | hci_dev_unlock(hdev); | ||
130 | } | ||
131 | |||
113 | static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | 132 | static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) |
114 | { | 133 | { |
115 | struct hci_rp_write_link_policy *rp = (void *) skb->data; | 134 | struct hci_rp_write_link_policy *rp = (void *) skb->data; |
@@ -128,13 +147,41 @@ static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | |||
128 | hci_dev_lock(hdev); | 147 | hci_dev_lock(hdev); |
129 | 148 | ||
130 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); | 149 | conn = hci_conn_hash_lookup_handle(hdev, __le16_to_cpu(rp->handle)); |
131 | if (conn) { | 150 | if (conn) |
132 | conn->link_policy = get_unaligned_le16(sent + 2); | 151 | conn->link_policy = get_unaligned_le16(sent + 2); |
133 | } | ||
134 | 152 | ||
135 | hci_dev_unlock(hdev); | 153 | hci_dev_unlock(hdev); |
136 | } | 154 | } |
137 | 155 | ||
156 | static void hci_cc_read_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | ||
157 | { | ||
158 | struct hci_rp_read_def_link_policy *rp = (void *) skb->data; | ||
159 | |||
160 | BT_DBG("%s status 0x%x", hdev->name, rp->status); | ||
161 | |||
162 | if (rp->status) | ||
163 | return; | ||
164 | |||
165 | hdev->link_policy = __le16_to_cpu(rp->policy); | ||
166 | } | ||
167 | |||
168 | static void hci_cc_write_def_link_policy(struct hci_dev *hdev, struct sk_buff *skb) | ||
169 | { | ||
170 | __u8 status = *((__u8 *) skb->data); | ||
171 | void *sent; | ||
172 | |||
173 | BT_DBG("%s status 0x%x", hdev->name, status); | ||
174 | |||
175 | sent = hci_sent_cmd_data(hdev, HCI_OP_WRITE_DEF_LINK_POLICY); | ||
176 | if (!sent) | ||
177 | return; | ||
178 | |||
179 | if (!status) | ||
180 | hdev->link_policy = get_unaligned_le16(sent); | ||
181 | |||
182 | hci_req_complete(hdev, status); | ||
183 | } | ||
184 | |||
138 | static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) | 185 | static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) |
139 | { | 186 | { |
140 | __u8 status = *((__u8 *) skb->data); | 187 | __u8 status = *((__u8 *) skb->data); |
@@ -347,8 +394,8 @@ static void hci_cc_read_local_version(struct hci_dev *hdev, struct sk_buff *skb) | |||
347 | return; | 394 | return; |
348 | 395 | ||
349 | hdev->hci_ver = rp->hci_ver; | 396 | hdev->hci_ver = rp->hci_ver; |
350 | hdev->hci_rev = btohs(rp->hci_rev); | 397 | hdev->hci_rev = __le16_to_cpu(rp->hci_rev); |
351 | hdev->manufacturer = btohs(rp->manufacturer); | 398 | hdev->manufacturer = __le16_to_cpu(rp->manufacturer); |
352 | 399 | ||
353 | BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, | 400 | BT_DBG("%s manufacturer %d hci ver %d:%d", hdev->name, |
354 | hdev->manufacturer, | 401 | hdev->manufacturer, |
@@ -690,14 +737,6 @@ static inline void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *s | |||
690 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp); | 737 | hci_send_cmd(hdev, HCI_OP_READ_REMOTE_FEATURES, sizeof(cp), &cp); |
691 | } | 738 | } |
692 | 739 | ||
693 | /* Set link policy */ | ||
694 | if (conn->type == ACL_LINK && hdev->link_policy) { | ||
695 | struct hci_cp_write_link_policy cp; | ||
696 | cp.handle = ev->handle; | ||
697 | cp.policy = cpu_to_le16(hdev->link_policy); | ||
698 | hci_send_cmd(hdev, HCI_OP_WRITE_LINK_POLICY, sizeof(cp), &cp); | ||
699 | } | ||
700 | |||
701 | /* Set packet type for incoming connection */ | 740 | /* Set packet type for incoming connection */ |
702 | if (!conn->out && hdev->hci_ver < 3) { | 741 | if (!conn->out && hdev->hci_ver < 3) { |
703 | struct hci_cp_change_conn_ptype cp; | 742 | struct hci_cp_change_conn_ptype cp; |
@@ -974,10 +1013,22 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk | |||
974 | hci_cc_role_discovery(hdev, skb); | 1013 | hci_cc_role_discovery(hdev, skb); |
975 | break; | 1014 | break; |
976 | 1015 | ||
1016 | case HCI_OP_READ_LINK_POLICY: | ||
1017 | hci_cc_read_link_policy(hdev, skb); | ||
1018 | break; | ||
1019 | |||
977 | case HCI_OP_WRITE_LINK_POLICY: | 1020 | case HCI_OP_WRITE_LINK_POLICY: |
978 | hci_cc_write_link_policy(hdev, skb); | 1021 | hci_cc_write_link_policy(hdev, skb); |
979 | break; | 1022 | break; |
980 | 1023 | ||
1024 | case HCI_OP_READ_DEF_LINK_POLICY: | ||
1025 | hci_cc_read_def_link_policy(hdev, skb); | ||
1026 | break; | ||
1027 | |||
1028 | case HCI_OP_WRITE_DEF_LINK_POLICY: | ||
1029 | hci_cc_write_def_link_policy(hdev, skb); | ||
1030 | break; | ||
1031 | |||
981 | case HCI_OP_RESET: | 1032 | case HCI_OP_RESET: |
982 | hci_cc_reset(hdev, skb); | 1033 | hci_cc_reset(hdev, skb); |
983 | break; | 1034 | break; |