aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/smp.c
diff options
context:
space:
mode:
authorVinicius Costa Gomes <vinicius.gomes@openbossa.org>2011-01-26 19:42:57 -0500
committerGustavo F. Padovan <padovan@profusion.mobi>2011-06-13 15:05:34 -0400
commitf1cb9af557dd8fb5d98fbcc4b5d3eb9d6d235af7 (patch)
treee2701e2cecfbf5cea1a079a7a87f8bfe020b7598 /net/bluetooth/smp.c
parent9b3d67405b17d61ba8be9d824222fb410f487b8a (diff)
Bluetooth: Add support for resuming socket when SMP is finished
This adds support for resuming the user space traffic when SMP negotiation is complete. Signed-off-by: Vinicius Costa Gomes <vinicius.gomes@openbossa.org> Signed-off-by: Gustavo F. Padovan <padovan@profusion.mobi>
Diffstat (limited to 'net/bluetooth/smp.c')
-rw-r--r--net/bluetooth/smp.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c
index 69839797b7dc..da46d76fc13d 100644
--- a/net/bluetooth/smp.c
+++ b/net/bluetooth/smp.c
@@ -336,9 +336,13 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
336{ 336{
337 struct smp_cmd_security_req *rp = (void *) skb->data; 337 struct smp_cmd_security_req *rp = (void *) skb->data;
338 struct smp_cmd_pairing cp; 338 struct smp_cmd_pairing cp;
339 struct hci_conn *hcon = conn->hcon;
339 340
340 BT_DBG("conn %p", conn); 341 BT_DBG("conn %p", conn);
341 342
343 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
344 return;
345
342 skb_pull(skb, sizeof(*rp)); 346 skb_pull(skb, sizeof(*rp));
343 memset(&cp, 0, sizeof(cp)); 347 memset(&cp, 0, sizeof(cp));
344 348
@@ -353,6 +357,20 @@ static void smp_cmd_security_req(struct l2cap_conn *conn, struct sk_buff *skb)
353 memcpy(&conn->preq[1], &cp, sizeof(cp)); 357 memcpy(&conn->preq[1], &cp, sizeof(cp));
354 358
355 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp); 359 smp_send_cmd(conn, SMP_CMD_PAIRING_REQ, sizeof(cp), &cp);
360
361 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
362}
363
364static __u8 seclevel_to_authreq(__u8 level)
365{
366 switch (level) {
367 case BT_SECURITY_HIGH:
368 /* For now we don't support bonding */
369 return SMP_AUTH_MITM;
370
371 default:
372 return SMP_AUTH_NONE;
373 }
356} 374}
357 375
358int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level) 376int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
@@ -365,21 +383,16 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
365 if (IS_ERR(hcon->hdev->tfm)) 383 if (IS_ERR(hcon->hdev->tfm))
366 return 1; 384 return 1;
367 385
368 switch (sec_level) { 386 if (test_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend))
369 case BT_SECURITY_MEDIUM: 387 return 0;
370 /* Encrypted, no MITM protection */
371 authreq = HCI_AT_NO_BONDING_MITM;
372 break;
373 388
374 case BT_SECURITY_HIGH: 389 if (sec_level == BT_SECURITY_LOW)
375 /* Bonding, MITM protection */ 390 return 1;
376 authreq = HCI_AT_GENERAL_BONDING_MITM;
377 break;
378 391
379 case BT_SECURITY_LOW: 392 if (hcon->sec_level >= sec_level)
380 default:
381 return 1; 393 return 1;
382 } 394
395 authreq = seclevel_to_authreq(sec_level);
383 396
384 if (hcon->link_mode & HCI_LM_MASTER) { 397 if (hcon->link_mode & HCI_LM_MASTER) {
385 struct smp_cmd_pairing cp; 398 struct smp_cmd_pairing cp;
@@ -400,6 +413,9 @@ int smp_conn_security(struct l2cap_conn *conn, __u8 sec_level)
400 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp); 413 smp_send_cmd(conn, SMP_CMD_SECURITY_REQ, sizeof(cp), &cp);
401 } 414 }
402 415
416 hcon->pending_sec_level = sec_level;
417 set_bit(HCI_CONN_ENCRYPT_PEND, &hcon->pend);
418
403 return 0; 419 return 0;
404} 420}
405 421