aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth
diff options
context:
space:
mode:
Diffstat (limited to 'net/bluetooth')
-rw-r--r--net/bluetooth/hci_conn.c2
-rw-r--r--net/bluetooth/hci_core.c35
-rw-r--r--net/bluetooth/hci_event.c75
3 files changed, 89 insertions, 23 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 69c64ce054fb..6175ce841e9e 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -65,6 +65,8 @@ void hci_acl_connect(struct hci_conn *conn)
65 65
66 conn->attempt++; 66 conn->attempt++;
67 67
68 conn->link_policy = hdev->link_policy;
69
68 memset(&cp, 0, sizeof(cp)); 70 memset(&cp, 0, sizeof(cp));
69 bacpy(&cp.bdaddr, &conn->dst); 71 bacpy(&cp.bdaddr, &conn->dst);
70 cp.pscan_rep_mode = 0x02; 72 cp.pscan_rep_mode = 0x02;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index aec6929f5c16..69b2c1aac08a 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -279,10 +279,20 @@ static void hci_encrypt_req(struct hci_dev *hdev, unsigned long opt)
279 279
280 BT_DBG("%s %x", hdev->name, encrypt); 280 BT_DBG("%s %x", hdev->name, encrypt);
281 281
282 /* Authentication */ 282 /* Encryption */
283 hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt); 283 hci_send_cmd(hdev, HCI_OP_WRITE_ENCRYPT_MODE, 1, &encrypt);
284} 284}
285 285
286static void hci_linkpol_req(struct hci_dev *hdev, unsigned long opt)
287{
288 __le16 policy = cpu_to_le16(opt);
289
290 BT_DBG("%s %x", hdev->name, opt);
291
292 /* Default link policy */
293 hci_send_cmd(hdev, HCI_OP_WRITE_DEF_LINK_POLICY, 2, &policy);
294}
295
286/* Get HCI device by index. 296/* Get HCI device by index.
287 * Device is held on return. */ 297 * Device is held on return. */
288struct hci_dev *hci_dev_get(int index) 298struct hci_dev *hci_dev_get(int index)
@@ -694,32 +704,35 @@ int hci_dev_cmd(unsigned int cmd, void __user *arg)
694 msecs_to_jiffies(HCI_INIT_TIMEOUT)); 704 msecs_to_jiffies(HCI_INIT_TIMEOUT));
695 break; 705 break;
696 706
697 case HCISETPTYPE:
698 hdev->pkt_type = (__u16) dr.dev_opt;
699 break;
700
701 case HCISETLINKPOL: 707 case HCISETLINKPOL:
702 hdev->link_policy = (__u16) dr.dev_opt; 708 err = hci_request(hdev, hci_linkpol_req, dr.dev_opt,
709 msecs_to_jiffies(HCI_INIT_TIMEOUT));
703 break; 710 break;
704 711
705 case HCISETLINKMODE: 712 case HCISETLINKMODE:
706 hdev->link_mode = ((__u16) dr.dev_opt) & (HCI_LM_MASTER | HCI_LM_ACCEPT); 713 hdev->link_mode = ((__u16) dr.dev_opt) &
714 (HCI_LM_MASTER | HCI_LM_ACCEPT);
715 break;
716
717 case HCISETPTYPE:
718 hdev->pkt_type = (__u16) dr.dev_opt;
707 break; 719 break;
708 720
709 case HCISETACLMTU: 721 case HCISETACLMTU:
710 hdev->acl_mtu = *((__u16 *)&dr.dev_opt + 1); 722 hdev->acl_mtu = *((__u16 *) &dr.dev_opt + 1);
711 hdev->acl_pkts = *((__u16 *)&dr.dev_opt + 0); 723 hdev->acl_pkts = *((__u16 *) &dr.dev_opt + 0);
712 break; 724 break;
713 725
714 case HCISETSCOMTU: 726 case HCISETSCOMTU:
715 hdev->sco_mtu = *((__u16 *)&dr.dev_opt + 1); 727 hdev->sco_mtu = *((__u16 *) &dr.dev_opt + 1);
716 hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0); 728 hdev->sco_pkts = *((__u16 *) &dr.dev_opt + 0);
717 break; 729 break;
718 730
719 default: 731 default:
720 err = -EINVAL; 732 err = -EINVAL;
721 break; 733 break;
722 } 734 }
735
723 hci_dev_put(hdev); 736 hci_dev_put(hdev);
724 return err; 737 return err;
725} 738}
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;