aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/hci_conn.c
diff options
context:
space:
mode:
authorIngo Molnar <mingo@elte.hu>2008-07-31 12:43:41 -0400
committerIngo Molnar <mingo@elte.hu>2008-07-31 12:43:41 -0400
commit85e9ca333d03fbd56b9e123c8456f0d98e20faad (patch)
tree7bb15ada5f536950efa23ad60ea9eea60380ca1c /net/bluetooth/hci_conn.c
parenta300bec952127d9a15e666b391bb35c9aecb3002 (diff)
parent6e86841d05f371b5b9b86ce76c02aaee83352298 (diff)
Merge branch 'linus' into timers/hpet
Diffstat (limited to 'net/bluetooth/hci_conn.c')
-rw-r--r--net/bluetooth/hci_conn.c96
1 files changed, 76 insertions, 20 deletions
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index f8880261da0e..ca8d05245ca0 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -59,24 +59,31 @@ void hci_acl_connect(struct hci_conn *conn)
59 BT_DBG("%p", conn); 59 BT_DBG("%p", conn);
60 60
61 conn->state = BT_CONNECT; 61 conn->state = BT_CONNECT;
62 conn->out = 1; 62 conn->out = 1;
63
63 conn->link_mode = HCI_LM_MASTER; 64 conn->link_mode = HCI_LM_MASTER;
64 65
65 conn->attempt++; 66 conn->attempt++;
66 67
68 conn->link_policy = hdev->link_policy;
69
67 memset(&cp, 0, sizeof(cp)); 70 memset(&cp, 0, sizeof(cp));
68 bacpy(&cp.bdaddr, &conn->dst); 71 bacpy(&cp.bdaddr, &conn->dst);
69 cp.pscan_rep_mode = 0x02; 72 cp.pscan_rep_mode = 0x02;
70 73
71 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst)) && 74 if ((ie = hci_inquiry_cache_lookup(hdev, &conn->dst))) {
72 inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) { 75 if (inquiry_entry_age(ie) <= INQUIRY_ENTRY_AGE_MAX) {
73 cp.pscan_rep_mode = ie->data.pscan_rep_mode; 76 cp.pscan_rep_mode = ie->data.pscan_rep_mode;
74 cp.pscan_mode = ie->data.pscan_mode; 77 cp.pscan_mode = ie->data.pscan_mode;
75 cp.clock_offset = ie->data.clock_offset | cpu_to_le16(0x8000); 78 cp.clock_offset = ie->data.clock_offset |
79 cpu_to_le16(0x8000);
80 }
81
76 memcpy(conn->dev_class, ie->data.dev_class, 3); 82 memcpy(conn->dev_class, ie->data.dev_class, 3);
83 conn->ssp_mode = ie->data.ssp_mode;
77 } 84 }
78 85
79 cp.pkt_type = cpu_to_le16(hdev->pkt_type & ACL_PTYPE_MASK); 86 cp.pkt_type = cpu_to_le16(conn->pkt_type);
80 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER)) 87 if (lmp_rswitch_capable(hdev) && !(hdev->link_mode & HCI_LM_MASTER))
81 cp.role_switch = 0x01; 88 cp.role_switch = 0x01;
82 else 89 else
@@ -122,7 +129,7 @@ void hci_add_sco(struct hci_conn *conn, __u16 handle)
122 conn->out = 1; 129 conn->out = 1;
123 130
124 cp.handle = cpu_to_le16(handle); 131 cp.handle = cpu_to_le16(handle);
125 cp.pkt_type = cpu_to_le16(hdev->pkt_type & SCO_PTYPE_MASK); 132 cp.pkt_type = cpu_to_le16(conn->pkt_type);
126 133
127 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp); 134 hci_send_cmd(hdev, HCI_OP_ADD_SCO, sizeof(cp), &cp);
128} 135}
@@ -138,7 +145,7 @@ void hci_setup_sync(struct hci_conn *conn, __u16 handle)
138 conn->out = 1; 145 conn->out = 1;
139 146
140 cp.handle = cpu_to_le16(handle); 147 cp.handle = cpu_to_le16(handle);
141 cp.pkt_type = cpu_to_le16(hdev->esco_type); 148 cp.pkt_type = cpu_to_le16(conn->pkt_type);
142 149
143 cp.tx_bandwidth = cpu_to_le32(0x00001f40); 150 cp.tx_bandwidth = cpu_to_le32(0x00001f40);
144 cp.rx_bandwidth = cpu_to_le32(0x00001f40); 151 cp.rx_bandwidth = cpu_to_le32(0x00001f40);
@@ -163,11 +170,13 @@ static void hci_conn_timeout(unsigned long arg)
163 170
164 switch (conn->state) { 171 switch (conn->state) {
165 case BT_CONNECT: 172 case BT_CONNECT:
173 case BT_CONNECT2:
166 if (conn->type == ACL_LINK) 174 if (conn->type == ACL_LINK)
167 hci_acl_connect_cancel(conn); 175 hci_acl_connect_cancel(conn);
168 else 176 else
169 hci_acl_disconn(conn, 0x13); 177 hci_acl_disconn(conn, 0x13);
170 break; 178 break;
179 case BT_CONFIG:
171 case BT_CONNECTED: 180 case BT_CONNECTED:
172 hci_acl_disconn(conn, 0x13); 181 hci_acl_disconn(conn, 0x13);
173 break; 182 break;
@@ -199,13 +208,28 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
199 return NULL; 208 return NULL;
200 209
201 bacpy(&conn->dst, dst); 210 bacpy(&conn->dst, dst);
202 conn->hdev = hdev; 211 conn->hdev = hdev;
203 conn->type = type; 212 conn->type = type;
204 conn->mode = HCI_CM_ACTIVE; 213 conn->mode = HCI_CM_ACTIVE;
205 conn->state = BT_OPEN; 214 conn->state = BT_OPEN;
206 215
207 conn->power_save = 1; 216 conn->power_save = 1;
208 217
218 switch (type) {
219 case ACL_LINK:
220 conn->pkt_type = hdev->pkt_type & ACL_PTYPE_MASK;
221 break;
222 case SCO_LINK:
223 if (lmp_esco_capable(hdev))
224 conn->pkt_type = hdev->esco_type & SCO_ESCO_MASK;
225 else
226 conn->pkt_type = hdev->pkt_type & SCO_PTYPE_MASK;
227 break;
228 case ESCO_LINK:
229 conn->pkt_type = hdev->esco_type;
230 break;
231 }
232
209 skb_queue_head_init(&conn->data_q); 233 skb_queue_head_init(&conn->data_q);
210 234
211 setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn); 235 setup_timer(&conn->disc_timer, hci_conn_timeout, (unsigned long)conn);
@@ -221,8 +245,6 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
221 if (hdev->notify) 245 if (hdev->notify)
222 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD); 246 hdev->notify(hdev, HCI_NOTIFY_CONN_ADD);
223 247
224 hci_conn_add_sysfs(conn);
225
226 tasklet_enable(&hdev->tx_task); 248 tasklet_enable(&hdev->tx_task);
227 249
228 return conn; 250 return conn;
@@ -254,12 +276,14 @@ int hci_conn_del(struct hci_conn *conn)
254 } 276 }
255 277
256 tasklet_disable(&hdev->tx_task); 278 tasklet_disable(&hdev->tx_task);
279
257 hci_conn_hash_del(hdev, conn); 280 hci_conn_hash_del(hdev, conn);
258 if (hdev->notify) 281 if (hdev->notify)
259 hdev->notify(hdev, HCI_NOTIFY_CONN_DEL); 282 hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);
283
260 tasklet_enable(&hdev->tx_task); 284 tasklet_enable(&hdev->tx_task);
285
261 skb_queue_purge(&conn->data_q); 286 skb_queue_purge(&conn->data_q);
262 hci_conn_del_sysfs(conn);
263 287
264 return 0; 288 return 0;
265} 289}
@@ -355,13 +379,21 @@ int hci_conn_auth(struct hci_conn *conn)
355{ 379{
356 BT_DBG("conn %p", conn); 380 BT_DBG("conn %p", conn);
357 381
382 if (conn->ssp_mode > 0 && conn->hdev->ssp_mode > 0) {
383 if (!(conn->auth_type & 0x01)) {
384 conn->auth_type = HCI_AT_GENERAL_BONDING_MITM;
385 conn->link_mode &= ~HCI_LM_AUTH;
386 }
387 }
388
358 if (conn->link_mode & HCI_LM_AUTH) 389 if (conn->link_mode & HCI_LM_AUTH)
359 return 1; 390 return 1;
360 391
361 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 392 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
362 struct hci_cp_auth_requested cp; 393 struct hci_cp_auth_requested cp;
363 cp.handle = cpu_to_le16(conn->handle); 394 cp.handle = cpu_to_le16(conn->handle);
364 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, sizeof(cp), &cp); 395 hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED,
396 sizeof(cp), &cp);
365 } 397 }
366 return 0; 398 return 0;
367} 399}
@@ -373,7 +405,7 @@ int hci_conn_encrypt(struct hci_conn *conn)
373 BT_DBG("conn %p", conn); 405 BT_DBG("conn %p", conn);
374 406
375 if (conn->link_mode & HCI_LM_ENCRYPT) 407 if (conn->link_mode & HCI_LM_ENCRYPT)
376 return 1; 408 return hci_conn_auth(conn);
377 409
378 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend)) 410 if (test_and_set_bit(HCI_CONN_ENCRYPT_PEND, &conn->pend))
379 return 0; 411 return 0;
@@ -382,7 +414,8 @@ int hci_conn_encrypt(struct hci_conn *conn)
382 struct hci_cp_set_conn_encrypt cp; 414 struct hci_cp_set_conn_encrypt cp;
383 cp.handle = cpu_to_le16(conn->handle); 415 cp.handle = cpu_to_le16(conn->handle);
384 cp.encrypt = 1; 416 cp.encrypt = 1;
385 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT, sizeof(cp), &cp); 417 hci_send_cmd(conn->hdev, HCI_OP_SET_CONN_ENCRYPT,
418 sizeof(cp), &cp);
386 } 419 }
387 return 0; 420 return 0;
388} 421}
@@ -396,7 +429,8 @@ int hci_conn_change_link_key(struct hci_conn *conn)
396 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) { 429 if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->pend)) {
397 struct hci_cp_change_conn_link_key cp; 430 struct hci_cp_change_conn_link_key cp;
398 cp.handle = cpu_to_le16(conn->handle); 431 cp.handle = cpu_to_le16(conn->handle);
399 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY, sizeof(cp), &cp); 432 hci_send_cmd(conn->hdev, HCI_OP_CHANGE_CONN_LINK_KEY,
433 sizeof(cp), &cp);
400 } 434 }
401 return 0; 435 return 0;
402} 436}
@@ -498,6 +532,8 @@ void hci_conn_hash_flush(struct hci_dev *hdev)
498 532
499 c->state = BT_CLOSED; 533 c->state = BT_CLOSED;
500 534
535 hci_conn_del_sysfs(c);
536
501 hci_proto_disconn_ind(c, 0x16); 537 hci_proto_disconn_ind(c, 0x16);
502 hci_conn_del(c); 538 hci_conn_del(c);
503 } 539 }
@@ -600,3 +636,23 @@ int hci_get_conn_info(struct hci_dev *hdev, void __user *arg)
600 636
601 return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0; 637 return copy_to_user(ptr, &ci, sizeof(ci)) ? -EFAULT : 0;
602} 638}
639
640int hci_get_auth_info(struct hci_dev *hdev, void __user *arg)
641{
642 struct hci_auth_info_req req;
643 struct hci_conn *conn;
644
645 if (copy_from_user(&req, arg, sizeof(req)))
646 return -EFAULT;
647
648 hci_dev_lock_bh(hdev);
649 conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &req.bdaddr);
650 if (conn)
651 req.type = conn->auth_type;
652 hci_dev_unlock_bh(hdev);
653
654 if (!conn)
655 return -ENOENT;
656
657 return copy_to_user(arg, &req, sizeof(req)) ? -EFAULT : 0;
658}