|
From: Anders J. <and...@us...> - 2003-05-22 15:17:36
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Tag Comment
---- ----------- ----------- --- -------
sec_client.c 1.26 1.27=20=20=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
Removed global request struct, replaced with a ringbuffer as we need to=20
be able to receive more than one request before the sec client has a=20
chance to read data. Will solve the problem with linkeys which aren't
saved due to overwrite of previous data.
The diff of the modified file(s):
--- sec_client.c 2002/08/01 16:19:29 1.26
+++ sec_client.c 2003/05/22 14:51:11 1.27
@@ -107,6 +107,7 @@
#define BUFFER_SIZE 256
#define MAX_EVENT_DATA_LENGTH 16
#define MAX_LINKKEYLISTSIZE 255 /* for now */
+#define MAX_QUEUE_ENTRIES 5
=20
/****************** TYPE DEFINITION SECTION ******************************=
***/
=20
@@ -131,7 +132,7 @@ enum originator_types {
KERNEL
};
=20
-struct security_query {
+typedef struct security_query {
u16 request_type; /* out */
u32 request_value; /* out */
u8 remote_bd[BD_ADDRESS_SIZE];
@@ -143,6 +144,16 @@ struct security_query {
u16 request_result; /* in */=09
} security_query;
=20
+struct proc_buffer {
+ u8 elements;
+ u8 data[sizeof(security_query) * MAX_QUEUE_ENTRIES];
+ u32 in;
+ u32 out;
+} proc_buffer;
+
+
+=09
+
/****************** LOCAL FUNCTION DECLARATION SECTION *******************=
***/
=20
#ifdef __KERNEL__
@@ -297,7 +308,7 @@ static s32 sec_man_sock;
=20
void sec_client_shutdown()
{
- security_query.originator =3D KERNEL;=20=20
+ proc_buffer.elements =3D 0;
#ifdef __KERNEL__
D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->com=
m);
wake_up_interruptible(&sec_man_wq);
@@ -313,9 +324,9 @@ sec_man_init(enum security_requests user
sec_man_sock =3D open_socket(SEC_MAN_SRV_SOCK);
#endif
init_link_key_list();
-
- /* To indicate that nothing is ready */
- security_query.originator =3D SEC_CLIENT;
+ proc_buffer.in =3D 0;
+ proc_buffer.out =3D 0;
+ proc_buffer.elements =3D 0;
=20=09
for(i =3D 0 ; i < BD_ADDRESS_SIZE ; i++) {
null_bd_addr[i] =3D 0;
@@ -503,10 +514,13 @@ sec_man_remove_proc_file(void)
=20
/* fixme -- add return value for calling functions to indicate status of=
=20
check */
-void=20
+s32
sec_man_check(enum security_requests user, BD_ADDR bd_addr, u32 service_da=
ta,
u32 user_data)
{
+ u32 pos;
+ security_query *query;
+=09
#ifndef __KERNEL__
if (sec_man_sock < 0) {
/* What to do if no security manager present?? */
@@ -522,27 +536,46 @@ sec_man_check(enum security_requests use
=20
}
#endif
+ D_PROC(__FUNCTION__ ": Current elements in buffer: %d\n", proc_buffer.ele=
ments);
=20
- security_query.request_type =3D user;
- security_query.request_value =3D service_data;
- memcpy(security_query.remote_bd, bd_addr, BD_ADDRESS_SIZE);
- security_query.originator =3D BT_SEC_MAN;
- security_query.originator_data =3D user_data;
- security_query.request_result =3D GENERAL_FAILURE;
+ if(proc_buffer.elements >=3D MAX_QUEUE_ENTRIES) {
+ D_ERR(__FUNCTION__ ": Not room for any queries at the moment");
+ return -1;
+ }
+=09
+ pos =3D proc_buffer.in;
+ proc_buffer.in +=3D sizeof(security_query);
+ ++proc_buffer.elements;
+ if(proc_buffer.in >=3D (sizeof(security_query) * MAX_QUEUE_ENTRIES)) {
+ proc_buffer.in =3D 0;
+ }
+
+ query =3D (security_query *)(proc_buffer.data + pos);
+
+ query->request_type =3D user;
+ query->request_value =3D service_data;
+ memcpy(query->remote_bd, bd_addr, BD_ADDRESS_SIZE);
+ query->originator =3D BT_SEC_MAN;
+ query->originator_data =3D user_data;
+ query->request_result =3D GENERAL_FAILURE;
=20
#ifdef __KERNEL__
D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->comm=
);
wake_up_interruptible(&sec_man_wq);
D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm);
+ return 0;
#else
- sec_man_doquery(sec_man_sock, (u8*) &security_query);
+ return sec_man_doquery(sec_man_sock, (u8*)query);
#endif
}
=20
-void
+s32
sec_man_event(enum security_requests user, BD_ADDR bd_addr, u8 event,
u8 *param, u8 param_len)
{
+ security_query *query;
+ u32 pos;
+=09
if (event =3D=3D HCI_VALUE_RETURN_LINK_KEYS)
{
/* Ok, link key has to be stored locally */
@@ -553,41 +586,59 @@ sec_man_event(enum security_requests use
link_key =3D create_link_key(bd_addr, link_key_str);
insert_link_key(link_key);
D_PROC("sec_man_event: Number of elements in list: %d\n", link_key_list.=
count);
+ return 0;
=20=09=09
}
else
{
#ifndef __KERNEL__
if (sec_man_sock < 0) {
- /* What to do if no security manager present?? */
+ return -1;
}
#endif
D_PROC("Called sec_man_event user:%d event:%02x\n", user, event);
- security_query.request_type =3D user;
- security_query.request_value =3D event;
+ D_PROC(__FUNCTION__ ": Current elements in buffer: %d\n", proc_buffer.el=
ements);
+
+ if(proc_buffer.elements >=3D MAX_QUEUE_ENTRIES) {
+ D_ERR(__FUNCTION__ ": Not room for any queries at the moment");
+ return -1;
+ }
+=09=09
+ pos =3D proc_buffer.in;
+ proc_buffer.in +=3D sizeof(security_query);
+ ++proc_buffer.elements;
+ if(proc_buffer.in >=3D (sizeof(security_query) * MAX_QUEUE_ENTRIES)) {
+ proc_buffer.in =3D 0;
+ }
+=09=09
+ query =3D (security_query *)(proc_buffer.data + pos);
+=09=09
+ query->request_type =3D user;
+ query->request_value =3D event;
if(bd_addr) {
- memcpy(security_query.remote_bd, bd_addr, BD_ADDRESS_SIZE);
+ memcpy(query->remote_bd, bd_addr, BD_ADDRESS_SIZE);
} else {
- memcpy(security_query.remote_bd, null_bd_addr, BD_ADDRESS_SIZE);
+ memcpy(query->remote_bd, null_bd_addr, BD_ADDRESS_SIZE);
}
=20=09=09
- security_query.originator =3D BT_SEC_MAN;
+ query->originator =3D BT_SEC_MAN;
=20=09=09
if (param_len > MAX_EVENT_DATA_LENGTH) {
D_PROC("Event data length too long, %d byte\n", param_len);
- memcpy(security_query.event_param, param, MAX_EVENT_DATA_LENGTH);
+ memcpy(query->event_param, param, MAX_EVENT_DATA_LENGTH);
} else {
- memcpy(security_query.event_param, param, param_len);
+ memcpy(query->event_param, param, param_len);
}
=20=09=09
- security_query.request_result =3D GENERAL_FAILURE;
+ query->request_result =3D GENERAL_FAILURE;
=20=09=09
#ifdef __KERNEL__
D_PROC("wake_up process %i (%s) awakening\n", current->pid, current->com=
m);
wake_up_interruptible(&sec_man_wq);
D_PROC("wake_up process %i (%s) woke up\n", current->pid, current->comm);
+ return 0;
#else
- sec_man_doquery(sec_man_sock, (u8*) &security_query);
+ return sec_man_doquery(sec_man_sock, (u8*)query);
#endif
}
}
@@ -674,24 +725,33 @@ s32 sec_man_read(struct inode *inode, st
char * buf, s32 count)
#endif
{
- s32 tmp;
-=09
+ u16 entry_size =3D sizeof(security_query);
D_PROC(__FUNCTION__ ": Someone is trying to read %d bytes from sec proc-f=
ile\n", count);
+ D_PROC(__FUNCTION__ ": Current elements in buffer: %d\n", proc_buffer.ele=
ments);
=20
cli();
- if (security_query.originator !=3D BT_SEC_MAN) {
- D_PROC(__FUNCTION__ ": No response yet, going to sleep\n");
+ if (proc_buffer.elements =3D=3D 0) {
+ D_PROC(__FUNCTION__ ": Nothing to be read, going to sleep\n");
interruptible_sleep_on(&sec_man_wq);
}
sti();
=20
- tmp =3D sizeof security_query;
- memcpy(buf, &security_query, tmp);
-=09
- D_PROC(__FUNCTION__ ": Returning %d bytes\n", tmp);
- security_query.originator =3D SEC_CLIENT; /* Change so we lock aga=
in */
=20=20=20=20=20=20=20=20=20
- return tmp;
+ if(proc_buffer.elements > 0)
+ {
+ memcpy(buf, proc_buffer.data + proc_buffer.out, entry_size);
+ D_PROC(__FUNCTION__ ": Returning %d bytes\n", entry_size);
+ --proc_buffer.elements;
+ proc_buffer.out +=3D entry_size;
+ if(proc_buffer.out >=3D (entry_size * MAX_QUEUE_ENTRIES)) {
+ proc_buffer.out =3D 0;
+ }
+ return entry_size;
+ } else {
+ /* If no data was available (weird case), send a EAGAIN
+ error to the client which probably will try again. */
+ return -EAGAIN;
+ }
}
=20
#ifdef USE_NEW_PROC
@@ -715,9 +775,6 @@ s32 sec_man_write(struct inode *inode, s
/* D_XMIT(__FUNCTION__ ": Preparing to send data to sec_con[%d]\n", secb_h=
dl->sec_con_id); */
if (sec_hdl->originator =3D=3D BT_SEC_MAN) /* o.k. new request */
{
- /* Change so we do not receive old data */
- security_query.originator =3D SEC_CLIENT;
-=09=09
switch (sec_hdl->request_type) {
case L2CAP:
D_PROC(__FUNCTION__ ": Message to L2CAP\n");
|