aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_event.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:47 -0400
committerMarcel Holtmann <marcel@holtmann.org>2008-07-14 14:13:47 -0400
commite4e8e37c42bdaaefcb84eeaef0dc1bc3f696f8f6 (patch)
tree7909e7f16b314ac0e2f68305ba38ebe7840d1951 /net/bluetooth/hci_event.c
parenta8746417e864da1ed36dd2432a399fbeb843c2a0 (diff)
[Bluetooth] Make use of the default link policy settings
The Bluetooth specification supports the default link policy settings on a per host controller basis. For every new connection the link manager would then use these settings. It is better to use this instead of bothering the controller on every connection setup to overwrite the default settings. Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
Diffstat (limited to 'net/bluetooth/hci_event.c')
-rw-r--r--net/bluetooth/hci_event.c75
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
113static 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
113static void hci_cc_write_link_policy(struct hci_dev *hdev, struct sk_buff *skb) 132static 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
156static 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
168static 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
138static void hci_cc_reset(struct hci_dev *hdev, struct sk_buff *skb) 185static 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;