[PATCH] android/socket: Use getsockopt to set buffer

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Andrei Emeltchenko <andrei.emeltchenko@xxxxxxxxx>

Use buffer size similar to one returned by getsockopt for RFCOMM socket.
If getsockopt fails use default value 25400 which is half of the default
RFCOMM kernel buffer (50800) calculated in kernel as:
RFCOMM_MAX_CREDITS * RFCOMM_DEFAULT_MTU * 10
---
 android/socket.c | 43 +++++++++++++++++++++++++++++++++++++------
 1 file changed, 37 insertions(+), 6 deletions(-)

diff --git a/android/socket.c b/android/socket.c
index 9020874..b5f7b1d 100644
--- a/android/socket.c
+++ b/android/socket.c
@@ -52,6 +52,8 @@
 
 #define SVC_HINT_OBEX 0x10
 
+#define SOCKET_BUFFER 25400 /* Half of the kernel buffer */
+
 static bdaddr_t adapter_addr;
 
 /* Simple list of RFCOMM server sockets */
@@ -71,9 +73,33 @@ struct rfcomm_sock {
 	bdaddr_t dst;
 	uint32_t service_handle;
 
+	unsigned char *buf;
+	int buf_size;
+
 	const struct profile_info *profile;
 };
 
+static void rfsock_set_buffer(struct rfcomm_sock *rfsock)
+{
+	socklen_t len = sizeof(int);
+	int size;
+
+	if (getsockopt(rfsock->real_sock, SOL_SOCKET, SO_RCVBUF, &size, &len)
+									< 0) {
+		warn("getsockopt(SO_RCVBUF) failed: %s", strerror(errno));
+		/* Use default buffer */
+		size = SOCKET_BUFFER;
+	} else {
+		/* Kernel doubles this */
+		size /= 2;
+	}
+
+	DBG("Set buffer size %d", size);
+
+	rfsock->buf = g_malloc(size);
+	rfsock->buf_size = size;
+}
+
 static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
 {
 	int fds[2] = {-1, -1};
@@ -90,6 +116,9 @@ static struct rfcomm_sock *create_rfsock(int sock, int *hal_fd)
 	*hal_fd = fds[1];
 	rfsock->real_sock = sock;
 
+	if (sock >= 0)
+		rfsock_set_buffer(rfsock);
+
 	return rfsock;
 }
 
@@ -121,6 +150,9 @@ static void cleanup_rfsock(gpointer data)
 	if (rfsock->service_handle)
 		bt_adapter_remove_record(rfsock->service_handle);
 
+	if (rfsock->buf)
+		g_free(rfsock->buf);
+
 	g_free(rfsock);
 }
 
@@ -487,7 +519,6 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
 	struct rfcomm_sock *rfsock = data;
-	unsigned char buf[1024];
 	int len, sent;
 
 	if (cond & G_IO_HUP) {
@@ -501,14 +532,14 @@ static gboolean sock_stack_event_cb(GIOChannel *io, GIOCondition cond,
 		goto fail;
 	}
 
-	len = read(rfsock->fd, buf, sizeof(buf));
+	len = read(rfsock->fd, rfsock->buf, rfsock->buf_size);
 	if (len <= 0) {
 		error("read(): %s", strerror(errno));
 		/* Read again */
 		return TRUE;
 	}
 
-	sent = try_write_all(rfsock->real_sock, buf, len);
+	sent = try_write_all(rfsock->real_sock, rfsock->buf, len);
 	if (sent < 0) {
 		error("write(): %s", strerror(errno));
 		goto fail;
@@ -526,7 +557,6 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 								gpointer data)
 {
 	struct rfcomm_sock *rfsock = data;
-	unsigned char buf[1024];
 	int len, sent;
 
 	if (cond & G_IO_HUP) {
@@ -540,14 +570,14 @@ static gboolean sock_rfcomm_event_cb(GIOChannel *io, GIOCondition cond,
 		goto fail;
 	}
 
-	len = read(rfsock->real_sock, buf, sizeof(buf));
+	len = read(rfsock->real_sock, rfsock->buf, rfsock->buf_size);
 	if (len <= 0) {
 		error("read(): %s", strerror(errno));
 		/* Read again */
 		return TRUE;
 	}
 
-	sent = try_write_all(rfsock->fd, buf, len);
+	sent = try_write_all(rfsock->fd, rfsock->buf, len);
 	if (sent < 0) {
 		error("write(): %s", strerror(errno));
 		goto fail;
@@ -866,6 +896,7 @@ static void sdp_search_cb(sdp_list_t *recs, int err, gpointer data)
 	}
 
 	rfsock->real_sock = g_io_channel_unix_get_fd(io);
+	rfsock_set_buffer(rfsock);
 	rfsock->channel = chan;
 	connections = g_list_append(connections, rfsock);
 
-- 
1.8.3.2

--
To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux