|
From: Peter K. <pk...@us...> - 2001-03-23 15:21:05
|
The following file was modified in linux/drivers/char/bluetooth:
Name Old version New version Comment
---- ----------- ----------- -------
sdp.c 1.67 1.68=20=20=20=20=20=20=20=20=20=20=20=20
The accompanying log:
sdp_database_write() should now handle split writes.
The diff of the modified file(s):
--- sdp.c 2001/03/06 11:06:24 1.67
+++ sdp.c 2001/03/23 15:21:04 1.68
@@ -315,6 +315,11 @@
#endif /* LINUX_VERSION_CODE */
#endif /* __KERNEL__ */
=20
+#ifdef __KERNEL__
+static bt_tx_buf *db_write_tx_buf;
+static s32 db_write_recv;
+#endif
+
#ifndef __KERNEL__
static s32 sdp_sock;
#endif
@@ -406,6 +411,9 @@
sdp_disconnect_req(i);
}
}=20=20
+
+ unsubscribe_bt_buf(db_write_tx_buf);
+ db_write_recv =3D 0;
}
=20
#ifdef __KERNEL__
@@ -907,11 +915,7 @@
=20
len =3D MIN(count, database_query.count);
=20
-#ifdef __KERNEL__
copy_to_user(buf, database_query.query, len);
-#else
- memcpy(buf, database_query.query, len);
-#endif
=20
if (database_query.count > len) {
memmove(database_query.query,
@@ -932,35 +936,60 @@
const char * buf, s32 count)
#endif
{
+ static data_struct db_hdl;
sdp_tx_buf *sdp_buf;
- bt_tx_buf *tx_buf;
- data_struct *db_hdl =3D (data_struct*) buf;
+ s32 read1 =3D 0;
+ s32 read2 =3D 0;
=20=09
D_PROC(__FUNCTION__ " Someone wrote %d bytes to sdp proc-file\n",count);
=20
- D_XMIT(__FUNCTION__ " preparing to send %d bytes data to sdp_con[%d]\n", =
count, db_hdl->sdp_con_id);
- PRINTPKT("Data to be sent to client:", db_hdl->data, db_hdl->len);
+ if (!bt_initiated())
+ return 0;
=20=09
- tx_buf =3D subscribe_bt_buf(sizeof(sdp_tx_buf) + db_hdl->len);
+ if (!db_write_tx_buf) {
+ read1 =3D MIN(sizeof db_hdl - db_write_recv, count);
+ copy_from_user(&db_hdl + db_write_recv, buf, read1);
=20
- if (!tx_buf) {
+ db_write_recv +=3D read1;
+
+ if (db_write_recv < sizeof db_hdl)
+ return read1;
+
+ db_write_tx_buf =3D subscribe_bt_buf(sizeof *sdp_buf + db_hdl.len);
+
+ if (!db_write_tx_buf) {
D_ERR(__FUNCTION__ " failed to get tx buffer\n");
- return -1;
+ db_write_recv -=3D read1;
+ return -ENOMEM;
}
=20
- tx_buf->cur_len =3D db_hdl->len;
- sdp_buf =3D (sdp_tx_buf*) (tx_buf->data);
+ db_write_tx_buf->cur_len =3D db_hdl.len;
=20
-#ifdef __KERNEL__
- copy_from_user(sdp_buf->frame, db_hdl->data, db_hdl->len);
-#else
- memcpy(sdp_buf->frame, db_hdl->data, db_hdl->len);
-#endif
+ count -=3D read1;
+ buf +=3D read1;
+ db_write_recv =3D 0;
+ }
=20
- l2cap_send_data(tx_buf, sdp_con_list[db_hdl->sdp_con_id].l2cap);
+ sdp_buf =3D (sdp_tx_buf*)db_write_tx_buf->data;
=20=09
- return count;
+ if (db_write_recv < db_hdl.len) {
+ read2 =3D MIN(db_hdl.len - db_write_recv, count);
+ copy_from_user(sdp_buf->frame + db_write_recv, buf, read2);
+ db_write_recv +=3D read2;
+
+ if (db_write_recv < db_hdl.len)
+ return read1 + read2;
}
+
+ D_XMIT(__FUNCTION__ " preparing to send %d bytes data to sdp_con[%d]\n", =
db_hdl.len, db_hdl.sdp_con_id);
+ PRINTPKT("Data to be sent to client:", db_hdl.data, db_hdl.len);
+
+ l2cap_send_data(db_write_tx_buf, sdp_con_list[db_hdl.sdp_con_id].l2cap);
+ db_write_tx_buf =3D NULL;
+ db_write_recv =3D 0;
+
+ return read1 + read2;
+}
#else /* __KERNEL__ */
=20
s32 sdp_doquery(s32 fd, u8 *request, s32 len)
@@ -968,11 +997,13 @@
s32 n;
u8 tmpbuf[512];
data_struct *db_hdl;
+ s32 recv;
=20
D_XMIT("sdp_doquery : sending request %d bytes\n", len);
write(fd, request, len);
=20=09
- n =3D read(fd, tmpbuf, 512);
+ if ((n =3D read(fd, tmpbuf, 512)) < 0)
+ return n;
=20
D_REC(__FUNCTION__ ", Received %d bytes\n", n);
=20=09
@@ -980,15 +1011,13 @@
=20=09
/* what if not all is written once */
=20
- if (n < (sizeof(data_struct) + db_hdl->len)) {
- D_ERR("sdp_doquery : only got partial response n:%d, db_hdl->len:%d\n", =
n, db_hdl->len);
- print_data("The request is:", request, len);
- return -1;
- }
+ for (recv =3D n; recv < sizeof *db_hdl + db_hdl->len; recv +=3D n)
+ if ((n =3D read(fd, tmpbuf + recv, 512 - recv)) < 0)
+ return n;
=20
sdp_send_data(&sdp_con_list[db_hdl->sdp_con_id], db_hdl->data, db_hdl->le=
n);=20
=20=09
- return n;
+ return recv;
}
#endif
=20
|