|
From: Anders J. <and...@us...> - 2004-01-31 02:46:47
|
The following files were modified in linux/drivers/char/bluetooth:
Name Old version New version Tag Comment
---- ----------- ----------- --- -------
bluetooth.c 1.247 1.248=20=20=20=20=20=20=20=20=20=20=20=20=20
l2cap.c 1.138 1.139=20=20=20=20=20=20=20=20=20=20=20=20=20
sec_client.c 1.29 1.30=20=20=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Added 2 new IOCTL:s, BBCONNECT and HCIAUTHENTICATION_ENCRYPTION.
Corrected the case where a disconnect_ind was received but
the PSM in the l2cap_con was invalid. Caused a never-ending while-loop.
The diff of the modified file(s):
--- bluetooth.c 2004/01/09 15:27:18 1.247
+++ bluetooth.c 2004/01/30 12:03:51 1.248
@@ -346,6 +346,18 @@ static tty_linebuffer tty_linebuf;
=20
#define BT_CON_TIMEOUT (10*HZ)
=20
+typedef struct secman_info {
+ bt_timer_obj timer;
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+ struct wait_queue *wq;
+#else
+ wait_queue_head_t wq;
+#endif
+ s32 status;
+} secman_info;
+
+static secman_info secman_handler;
+
/****************** FUNCTION DEFINITION SECTION **************************=
***/
=20
/*
@@ -615,8 +627,15 @@ __bt_ioctl(struct tty_struct *tty, struc
BT_DRIVER(__FUNCTION__ ": SDP_CONNECT\n");
return sdp_connect(btcon.bd, &btcon.pincode);
}
-=09
-
+ case BBCONNECT:
+ {
+ u8 *bd_addr;
+ /* argument is an object with all info to start a remote
+ connection */
+ copy_from_user(&btcon, (s32*)arg, size);
+ BT_DRIVER(__FUNCTION__ ": BB_CONNECT\n");
+ return lp_connect(btcon.bd, &btcon.pincode);
+ }
#ifdef CONFIG_BLUETOOTH_USE_SECURITY_MANAGER
case BT_GETCACHEDLINKKEY:
{
@@ -944,6 +963,32 @@ hci_inq_exit0:
break;
}
=20
+ case HCIAUTHENTICATION_ENCRYPTION:
+ {
+ u8 bd_addr[size];
+ BT_DRIVER(__FUNCTION__ ": HCIAUTHENTICATION_ENCRYPTION\n");
+ copy_from_user(bd_addr, (s32*)arg, size);
+ secman_handler.status =3D -1;
+ if(hci_authentication_requested_bd(bd_addr) < 0) {
+ return -1;
+ }
+ start_wq_timer(&secman_handler.timer, 30 * HZ,
+ &secman_handler.wq);
+ interruptible_sleep_on(&secman_handler.wq);
+ if(secman_handler.status !=3D 0) {
+ return -secman_handler.status;
+ }
+ if(hci_set_connection_encryption_bd(bd_addr, 1) < 0) {
+ return -1;
+ }
+ secman_handler.status =3D -1;
+ start_wq_timer(&secman_handler.timer, 10 * HZ,
+ &secman_handler.wq);
+ interruptible_sleep_on(&secman_handler.wq);
+ return -secman_handler.status;
+ }
+=09
+
case HCIREADCLOCKOFFSET:
{
/* Return parameters (4 bytes):
@@ -2855,7 +2900,11 @@ s32 bt_init(void)
bnep_init_module();
#endif
local_name[0] =3D 0;
-
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0)
+ secman_handler.wq =3D NULL;
+#else
+ init_waitqueue_head(&secman_handler.wq);
+#endif
return 0; /* success */
}
=20
@@ -3478,6 +3527,16 @@ wq_timeout(unsigned long ptr)
wake_up_interruptible(wq);
}
=20
+/* Used only if we are initiating a connection and this function is
+ called when either authentication or encryption is finished */
+void
+bt_secman_notify(s32 status)
+{
+ secman_handler.status =3D status;
+ wake_up_interruptible(&secman_handler.wq);
+ release_wq_timer(&secman_handler.timer);
+}=20=20
+
/************************ MODULE STUFF ***********************************=
***/
=20
#if defined(MODULE) || defined(__KERNEL__)
--- l2cap.c 2003/11/05 15:21:59 1.138
+++ l2cap.c 2004/01/30 12:03:53 1.139
@@ -1444,6 +1444,80 @@ lp_connect_cfm(u8 *bd_addr, u32 status,=20
}
}
=20=20
+/* Creates a new baseband connection if not already present */
+s32
+lp_connect(BD_ADDR bd, bt_pincode *pincode)
+{
+ l2cap_con *con;
+ s32 i, retval =3D 0;
+ u8 rev_bd[6];
+
+ /* Check bd_addr */
+ if (!bd[0] && !bd[1] && !bd[2] && !bd[3] && !bd[4] && !bd[5]) {
+ D_ERR(__FUNCTION__ ": No BD-addr\n");
+ return -EINVAL;
+ }
+ /* bd is big endian, reverse byte order to little endian */
+ for (i =3D 0; i < 6; i++) {
+ rev_bd[5-i] =3D bd[i];
+ }
+=09
+ if(get_con(rev_bd, ANY_STATE))
+ {
+ D_ERR(__FUNCTION__ ": Baseband connection already exists");
+ return -(MSGCODE(MSG_BT_INTERFACE, BT_ALREADYCONNECTED));
+ }
+
+ con =3D create_con(0/* not yet set */, get_cid(), 0/* not yet set */);
+
+ /* Check connection */
+ if (con =3D=3D NULL) {
+ D_ERR(__FUNCTION__ ": no connection created\n");
+ return -ENOMEM;
+ }
+
+ memcpy(con->remote_bd, rev_bd, 6);
+ print_data("bd", con->remote_bd, 6);
+ /* we are client */
+ con->initiator =3D 1;=20
+
+ /* Just clear some values, will not be used for this connection */
+ con->conf_req_ready=3D0;
+ con->conf_rsp_ready=3D0;
+ con->flush_timeout =3D FLUSHTIMEOUT_DEFAULT;
+ con->link_up =3D 0;
+ insert_con(con);
+
+=09
+ D_STATE(__FUNCTION__ ": create new baseband link\n");
+ /* Pincode is set per baseband link */
+ if(pincode) {
+ memcpy(con->pincode.data, pincode->data, 0x10);
+ con->pincode.len =3D pincode->len;
+ }
+
+ retval =3D lp_connect_req(con->remote_bd);
+ if(retval < 0) {
+ D_ERR(__FUNCTION__ ": failed (status %d)\n", retval);
+ delete_con(con);
+ return retval;
+ }
+
+ /* wait here until we received a lp_connect_cfm */
+ l2ca_wait(__FUNCTION__ ": wait baseband", con);
+=09=09
+ if (con->c_status !=3D RES_SUCCESS) {
+ D_ERR(__FUNCTION__ ": lp_connect_req failed, no connection (status %d)\n=
", con->c_status);
+ retval =3D -MSGCODE(MSG_LAYER_HCI, con->c_status);
+ delete_con(con);
+ return retval;
+ }
+ return retval;
+}=09
+=09
+=09
+=09
+=20
/* Indicates that one of the baseband connections has been shutdown */
s32
lp_disconnect_ind(u32 con_hdl)
@@ -1483,10 +1557,14 @@ lp_disconnect_ind(u32 con_hdl)
ENTERSTATE(con, W4_L2CA_DISCONNECT_RSP);
DSYS("closing l2cap con (%d,%d)\n",
con->local_cid, con->remote_cid);
-
+ if ((con->psm =3D=3D 0) || (get_upper(con->psm) =3D=3D &default_protoco=
l)) {
+ con->current_state =3D CLOSED;
+ delete_con(con);
+ } else {
/* notify upper layers that phys link is down */
get_upper(con->psm)->disc_ind(con);
}
+ }
=20
found =3D 1;
}
--- sec_client.c 2003/11/12 10:15:05 1.29
+++ sec_client.c 2004/01/30 12:03:54 1.30
@@ -57,6 +57,8 @@
#include <linux/bluetooth/hci_internal.h>
#include <linux/bluetooth/btmem.h>
#include <linux/bluetooth/l2cap.h>
+#include <linux/bluetooth/bluetooth.h>
+#include <linux/bluetooth/bt_errno.h>
#include <linux/proc_fs.h>
#else /* user mode */
#include <stdlib.h>
@@ -613,6 +615,13 @@ sec_man_event(enum security_requests use
case LINK_KEY_NOTIFICATION:
hci_write_stored_link_key(bd_addr, param, 0);
break;
+ case AUTHENTICATION_COMPLETE:
+ case ENCRYPTION_CHANGE:
+ pos =3D *param;
+ pos =3D MSGCODE(MSG_LAYER_HCI, pos);
+ bt_secman_notify(pos);
+ break;
+
default:
printk("Received event %d, no action\n", event);
}
|