fastboot: use cutils socket functions.
Now that cutils has cross-platform socket functionality, we can
restructure fastboot to remove platform-dependent networking code.
This CL adds socket_set_receive_timeout() to libcutils and combines the
fastboot socket code into a single implementation. It also adds TCP
functionality to fastboot sockets, but nothing uses it yet except for
the unit tests. A future CL will add the TCP protocol which will use
this TCP socket implementation.
Bug: http://b/26558551
Change-Id: If613fb348f9332b31fa2c88d67fb1e839923768a
diff --git a/fastboot/socket.h b/fastboot/socket.h
index 888b530..3e66c27 100644
--- a/fastboot/socket.h
+++ b/fastboot/socket.h
@@ -26,36 +26,41 @@
* SUCH DAMAGE.
*/
-// This file provides a class interface for cross-platform UDP functionality. The main fastboot
+// This file provides a class interface for cross-platform socket functionality. The main fastboot
// engine should not be using this interface directly, but instead should use a higher-level
-// interface that enforces the fastboot UDP protocol.
+// interface that enforces the fastboot protocol.
#ifndef SOCKET_H_
#define SOCKET_H_
-#include "android-base/macros.h"
-
#include <memory>
#include <string>
-// UdpSocket interface to be implemented for each platform.
-class UdpSocket {
+#include <android-base/macros.h>
+#include <cutils/sockets.h>
+
+// Socket interface to be implemented for each platform.
+class Socket {
public:
+ enum class Protocol { kTcp, kUdp };
+
// Creates a new client connection. Clients are connected to a specific hostname/port and can
// only send to that destination.
// On failure, |error| is filled (if non-null) and nullptr is returned.
- static std::unique_ptr<UdpSocket> NewUdpClient(const std::string& hostname, int port,
- std::string* error);
+ static std::unique_ptr<Socket> NewClient(Protocol protocol, const std::string& hostname,
+ int port, std::string* error);
// Creates a new server bound to local |port|. This is only meant for testing, during normal
// fastboot operation the device acts as the server.
- // The server saves sender addresses in Receive(), and uses the most recent address during
+ // A UDP server saves sender addresses in Receive(), and uses the most recent address during
// calls to Send().
- static std::unique_ptr<UdpSocket> NewUdpServer(int port);
+ static std::unique_ptr<Socket> NewServer(Protocol protocol, int port);
- virtual ~UdpSocket() = default;
+ // Destructor closes the socket if it's open.
+ virtual ~Socket();
- // Sends |length| bytes of |data|. Returns the number of bytes actually sent or -1 on error.
+ // Sends |length| bytes of |data|. For TCP sockets this will continue trying to send until all
+ // bytes are transmitted. Returns the number of bytes actually sent or -1 on error.
virtual ssize_t Send(const void* data, size_t length) = 0;
// Waits up to |timeout_ms| to receive up to |length| bytes of data. |timout_ms| of 0 will
@@ -63,14 +68,29 @@
// errno will be set to EAGAIN or EWOULDBLOCK.
virtual ssize_t Receive(void* data, size_t length, int timeout_ms) = 0;
+ // Calls Receive() until exactly |length| bytes have been received or an error occurs.
+ virtual ssize_t ReceiveAll(void* data, size_t length, int timeout_ms);
+
// Closes the socket. Returns 0 on success, -1 on error.
- virtual int Close() = 0;
+ virtual int Close();
+
+ // Accepts an incoming TCP connection. No effect for UDP sockets. Returns a new Socket
+ // connected to the client on success, nullptr on failure.
+ virtual std::unique_ptr<Socket> Accept() { return nullptr; }
protected:
// Protected constructor to force factory function use.
- UdpSocket() = default;
+ Socket(cutils_socket_t sock);
- DISALLOW_COPY_AND_ASSIGN(UdpSocket);
+ // Update the socket receive timeout if necessary.
+ bool SetReceiveTimeout(int timeout_ms);
+
+ cutils_socket_t sock_ = INVALID_SOCKET;
+
+ private:
+ int receive_timeout_ms_ = 0;
+
+ DISALLOW_COPY_AND_ASSIGN(Socket);
};
#endif // SOCKET_H_