OSDN Git Service

Add a method to check for available bytes on a socket
authorSharvil Nanavati <sharvil@google.com>
Thu, 28 Aug 2014 02:05:40 +0000 (19:05 -0700)
committerAndre Eisenbach <eisenbach@google.com>
Mon, 16 Mar 2015 23:51:30 +0000 (16:51 -0700)
The available bytes function shouldn't normally be required (and
if it is, the code design is probably bad and should be rethought) but
is introduced as a stop-gap until we can redesign the BTA code that
expects a priori knowledge of the number of bytes that can be read from
the socket.

This change also relaxes the requirement that on socket_register that
at least one of read_cb or write_cb must be specified.

osi/include/socket.h
osi/src/socket.c

index aadfd5b..e2d0888 100644 (file)
 
 #pragma once
 
+#include <stdbool.h>
 #include <stddef.h>
 #include <stdint.h>
+#include <sys/types.h>
 
 typedef struct reactor_t reactor_t;
 typedef struct socket_t socket_t;
@@ -78,11 +80,19 @@ ssize_t socket_write(const socket_t *socket, const void *buf, size_t count);
 // If |fd| is INVALID_FD, this function behaves the same as |socket_write|.
 ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, size_t count, int fd);
 
+// Returns the number of bytes that can be read from |socket| without blocking. On error,
+// this function returns -1. |socket| may not be NULL.
+//
+// Note: this function should not be part of the socket interface. It is only provided as
+//       a stop-gap until we can refactor away code that depends on a priori knowledge of
+//       the byte count. Do not use this function unless you need it while refactoring
+//       legacy bluedroid code.
+ssize_t socket_bytes_available(const socket_t *socket);
+
 // Registers |socket| with the |reactor|. When the socket becomes readable, |read_cb|
 // will be called. When the socket becomes writeable, |write_cb| will be called. The
 // |context| parameter is passed, untouched, to each of the callback routines. Neither
-// |socket| nor |reactor| may be NULL. |read_cb| or |write_cb|, but not both, may be NULL.
-// |context| may be NULL.
+// |socket| nor |reactor| may be NULL. |read_cb|, |write_cb|, and |context| may be NULL.
 void socket_register(socket_t *socket, reactor_t *reactor, void *context, socket_cb read_cb, socket_cb write_cb);
 
 // Unregisters |socket| from whichever reactor it is registered with, if any. This
index 687a670..6f41976 100644 (file)
 
 #define LOG_TAG "bt_osi_socket"
 
+#include <asm/ioctls.h>
 #include <assert.h>
 #include <errno.h>
 #include <netinet/in.h>
 #include <string.h>
+#include <sys/ioctl.h>
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <unistd.h>
@@ -179,9 +181,17 @@ ssize_t socket_write_and_transfer_fd(const socket_t *socket, const void *buf, si
   return ret;
 }
 
+ssize_t socket_bytes_available(const socket_t *socket) {
+  assert(socket != NULL);
+
+  int size = 0;
+  if (ioctl(socket->fd, FIONREAD, &size) == -1)
+    return -1;
+  return size;
+}
+
 void socket_register(socket_t *socket, reactor_t *reactor, void *context, socket_cb read_cb, socket_cb write_cb) {
   assert(socket != NULL);
-  assert(read_cb || write_cb);
 
   // Make sure the socket isn't currently registered.
   socket_unregister(socket);