Loading fastboot/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ LOCAL_STATIC_LIBRARIES := \ libdiagnose_usb \ libbase \ libcutils \ libgtest_host \ # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") LOCAL_CFLAGS_linux := -DUSE_F2FS Loading fastboot/socket.cpp +56 −14 Original line number Diff line number Diff line Loading @@ -89,7 +89,8 @@ class UdpSocket : public Socket { UdpSocket(Type type, cutils_socket_t sock); ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; private: Loading @@ -109,9 +110,20 @@ UdpSocket::UdpSocket(Type type, cutils_socket_t sock) : Socket(sock) { } } ssize_t UdpSocket::Send(const void* data, size_t length) { bool UdpSocket::Send(const void* data, size_t length) { return TEMP_FAILURE_RETRY(sendto(sock_, reinterpret_cast<const char*>(data), length, 0, reinterpret_cast<sockaddr*>(addr_.get()), addr_size_)); reinterpret_cast<sockaddr*>(addr_.get()), addr_size_)) == static_cast<ssize_t>(length); } bool UdpSocket::Send(std::vector<cutils_socket_buffer_t> buffers) { size_t total_length = 0; for (const auto& buffer : buffers) { total_length += buffer.length; } return TEMP_FAILURE_RETRY(socket_send_buffers_function_( sock_, buffers.data(), buffers.size())) == static_cast<ssize_t>(total_length); } ssize_t UdpSocket::Receive(void* data, size_t length, int timeout_ms) { Loading @@ -135,7 +147,8 @@ class TcpSocket : public Socket { public: TcpSocket(cutils_socket_t sock) : Socket(sock) {} ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; std::unique_ptr<Socket> Accept() override; Loading @@ -144,23 +157,52 @@ class TcpSocket : public Socket { DISALLOW_COPY_AND_ASSIGN(TcpSocket); }; ssize_t TcpSocket::Send(const void* data, size_t length) { size_t total = 0; bool TcpSocket::Send(const void* data, size_t length) { while (length > 0) { ssize_t sent = TEMP_FAILURE_RETRY(send(sock_, reinterpret_cast<const char*>(data), length, 0)); while (total < length) { ssize_t bytes = TEMP_FAILURE_RETRY( send(sock_, reinterpret_cast<const char*>(data) + total, length - total, 0)); if (sent == -1) { return false; } length -= sent; } if (bytes == -1) { if (total == 0) { return -1; return true; } bool TcpSocket::Send(std::vector<cutils_socket_buffer_t> buffers) { while (!buffers.empty()) { ssize_t sent = TEMP_FAILURE_RETRY( socket_send_buffers_function_(sock_, buffers.data(), buffers.size())); if (sent == -1) { return false; } // Adjust the buffers to skip past the bytes we've just sent. auto iter = buffers.begin(); while (sent > 0) { if (iter->length > static_cast<size_t>(sent)) { // Incomplete buffer write; adjust the buffer to point to the next byte to send. iter->length -= sent; iter->data = reinterpret_cast<const char*>(iter->data) + sent; break; } total += bytes; // Complete buffer write; move on to the next buffer. sent -= iter->length; ++iter; } return total; // Shortcut the common case: we've written everything remaining. if (iter == buffers.end()) { break; } buffers.erase(buffers.begin(), iter); } return true; } ssize_t TcpSocket::Receive(void* data, size_t length, int timeout_ms) { Loading fastboot/socket.h +23 −2 Original line number Diff line number Diff line Loading @@ -33,11 +33,15 @@ #ifndef SOCKET_H_ #define SOCKET_H_ #include <functional> #include <memory> #include <string> #include <utility> #include <vector> #include <android-base/macros.h> #include <cutils/sockets.h> #include <gtest/gtest_prod.h> // Socket interface to be implemented for each platform. class Socket { Loading @@ -64,8 +68,17 @@ class Socket { virtual ~Socket(); // 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; // bytes are transmitted. Returns true on success. virtual bool Send(const void* data, size_t length) = 0; // Sends |buffers| using multi-buffer write, which can be significantly faster than making // multiple calls. For UDP sockets |buffers| are all combined into a single datagram; for // TCP sockets this will continue sending until all buffers are fully transmitted. Returns true // on success. // // Note: This is non-functional for UDP server Sockets because it's not currently needed and // would require an additional sendto() variation of multi-buffer write. virtual bool Send(std::vector<cutils_socket_buffer_t> buffers) = 0; // Waits up to |timeout_ms| to receive up to |length| bytes of data. |timout_ms| of 0 will // block forever. Returns the number of bytes received or -1 on error/timeout. On timeout Loading Loading @@ -94,9 +107,17 @@ class Socket { cutils_socket_t sock_ = INVALID_SOCKET; // Non-class functions we want to override during tests to verify functionality. Implementation // should call this rather than using socket_send_buffers() directly. std::function<ssize_t(cutils_socket_t, cutils_socket_buffer_t*, size_t)> socket_send_buffers_function_ = &socket_send_buffers; private: int receive_timeout_ms_ = 0; FRIEND_TEST(SocketTest, TestTcpSendBuffers); FRIEND_TEST(SocketTest, TestUdpSendBuffers); DISALLOW_COPY_AND_ASSIGN(Socket); }; Loading fastboot/socket_mock.cpp +20 −11 Original line number Diff line number Diff line Loading @@ -38,26 +38,35 @@ SocketMock::~SocketMock() { } } ssize_t SocketMock::Send(const void* data, size_t length) { bool SocketMock::Send(const void* data, size_t length) { if (events_.empty()) { ADD_FAILURE() << "Send() was called when no message was expected"; return -1; return false; } if (events_.front().type != EventType::kSend) { ADD_FAILURE() << "Send() was called out-of-order"; return -1; return false; } std::string message(reinterpret_cast<const char*>(data), length); if (events_.front().message != message) { ADD_FAILURE() << "Send() expected " << events_.front().message << ", but got " << message; return -1; return false; } ssize_t return_value = events_.front().return_value; events_.pop(); return return_value; return true; } // Mock out multi-buffer send to be one large send, since that's what it should looks like from // the user's perspective. bool SocketMock::Send(std::vector<cutils_socket_buffer_t> buffers) { std::string data; for (const auto& buffer : buffers) { data.append(reinterpret_cast<const char*>(buffer.data), buffer.length); } return Send(data.data(), data.size()); } ssize_t SocketMock::Receive(void* data, size_t length, int /*timeout_ms*/) { Loading Loading @@ -106,13 +115,13 @@ std::unique_ptr<Socket> SocketMock::Accept() { } void SocketMock::ExpectSend(std::string message) { ssize_t return_value = message.length(); events_.push(Event(EventType::kSend, std::move(message), return_value, nullptr)); events_.push(Event(EventType::kSend, std::move(message), 0, nullptr)); } void SocketMock::ExpectSendFailure(std::string message) { events_.push(Event(EventType::kSend, std::move(message), -1, nullptr)); } // TODO: make this properly return false to the caller. //void SocketMock::ExpectSendFailure(std::string message) { // events_.push(Event(EventType::kSend, std::move(message), 0, nullptr)); //} void SocketMock::AddReceive(std::string message) { ssize_t return_value = message.length(); Loading fastboot/socket_mock.h +2 −4 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ class SocketMock : public Socket { SocketMock(); ~SocketMock() override; ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; int Close() override; virtual std::unique_ptr<Socket> Accept(); Loading @@ -64,9 +65,6 @@ class SocketMock : public Socket { // Adds an expectation for Send(). void ExpectSend(std::string message); // Adds an expectation for Send() that returns -1. void ExpectSendFailure(std::string message); // Adds data to provide for Receive(). void AddReceive(std::string message); Loading Loading
fastboot/Android.mk +1 −0 Original line number Diff line number Diff line Loading @@ -65,6 +65,7 @@ LOCAL_STATIC_LIBRARIES := \ libdiagnose_usb \ libbase \ libcutils \ libgtest_host \ # libf2fs_dlutils_host will dlopen("libf2fs_fmt_host_dyn") LOCAL_CFLAGS_linux := -DUSE_F2FS Loading
fastboot/socket.cpp +56 −14 Original line number Diff line number Diff line Loading @@ -89,7 +89,8 @@ class UdpSocket : public Socket { UdpSocket(Type type, cutils_socket_t sock); ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; private: Loading @@ -109,9 +110,20 @@ UdpSocket::UdpSocket(Type type, cutils_socket_t sock) : Socket(sock) { } } ssize_t UdpSocket::Send(const void* data, size_t length) { bool UdpSocket::Send(const void* data, size_t length) { return TEMP_FAILURE_RETRY(sendto(sock_, reinterpret_cast<const char*>(data), length, 0, reinterpret_cast<sockaddr*>(addr_.get()), addr_size_)); reinterpret_cast<sockaddr*>(addr_.get()), addr_size_)) == static_cast<ssize_t>(length); } bool UdpSocket::Send(std::vector<cutils_socket_buffer_t> buffers) { size_t total_length = 0; for (const auto& buffer : buffers) { total_length += buffer.length; } return TEMP_FAILURE_RETRY(socket_send_buffers_function_( sock_, buffers.data(), buffers.size())) == static_cast<ssize_t>(total_length); } ssize_t UdpSocket::Receive(void* data, size_t length, int timeout_ms) { Loading @@ -135,7 +147,8 @@ class TcpSocket : public Socket { public: TcpSocket(cutils_socket_t sock) : Socket(sock) {} ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; std::unique_ptr<Socket> Accept() override; Loading @@ -144,23 +157,52 @@ class TcpSocket : public Socket { DISALLOW_COPY_AND_ASSIGN(TcpSocket); }; ssize_t TcpSocket::Send(const void* data, size_t length) { size_t total = 0; bool TcpSocket::Send(const void* data, size_t length) { while (length > 0) { ssize_t sent = TEMP_FAILURE_RETRY(send(sock_, reinterpret_cast<const char*>(data), length, 0)); while (total < length) { ssize_t bytes = TEMP_FAILURE_RETRY( send(sock_, reinterpret_cast<const char*>(data) + total, length - total, 0)); if (sent == -1) { return false; } length -= sent; } if (bytes == -1) { if (total == 0) { return -1; return true; } bool TcpSocket::Send(std::vector<cutils_socket_buffer_t> buffers) { while (!buffers.empty()) { ssize_t sent = TEMP_FAILURE_RETRY( socket_send_buffers_function_(sock_, buffers.data(), buffers.size())); if (sent == -1) { return false; } // Adjust the buffers to skip past the bytes we've just sent. auto iter = buffers.begin(); while (sent > 0) { if (iter->length > static_cast<size_t>(sent)) { // Incomplete buffer write; adjust the buffer to point to the next byte to send. iter->length -= sent; iter->data = reinterpret_cast<const char*>(iter->data) + sent; break; } total += bytes; // Complete buffer write; move on to the next buffer. sent -= iter->length; ++iter; } return total; // Shortcut the common case: we've written everything remaining. if (iter == buffers.end()) { break; } buffers.erase(buffers.begin(), iter); } return true; } ssize_t TcpSocket::Receive(void* data, size_t length, int timeout_ms) { Loading
fastboot/socket.h +23 −2 Original line number Diff line number Diff line Loading @@ -33,11 +33,15 @@ #ifndef SOCKET_H_ #define SOCKET_H_ #include <functional> #include <memory> #include <string> #include <utility> #include <vector> #include <android-base/macros.h> #include <cutils/sockets.h> #include <gtest/gtest_prod.h> // Socket interface to be implemented for each platform. class Socket { Loading @@ -64,8 +68,17 @@ class Socket { virtual ~Socket(); // 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; // bytes are transmitted. Returns true on success. virtual bool Send(const void* data, size_t length) = 0; // Sends |buffers| using multi-buffer write, which can be significantly faster than making // multiple calls. For UDP sockets |buffers| are all combined into a single datagram; for // TCP sockets this will continue sending until all buffers are fully transmitted. Returns true // on success. // // Note: This is non-functional for UDP server Sockets because it's not currently needed and // would require an additional sendto() variation of multi-buffer write. virtual bool Send(std::vector<cutils_socket_buffer_t> buffers) = 0; // Waits up to |timeout_ms| to receive up to |length| bytes of data. |timout_ms| of 0 will // block forever. Returns the number of bytes received or -1 on error/timeout. On timeout Loading Loading @@ -94,9 +107,17 @@ class Socket { cutils_socket_t sock_ = INVALID_SOCKET; // Non-class functions we want to override during tests to verify functionality. Implementation // should call this rather than using socket_send_buffers() directly. std::function<ssize_t(cutils_socket_t, cutils_socket_buffer_t*, size_t)> socket_send_buffers_function_ = &socket_send_buffers; private: int receive_timeout_ms_ = 0; FRIEND_TEST(SocketTest, TestTcpSendBuffers); FRIEND_TEST(SocketTest, TestUdpSendBuffers); DISALLOW_COPY_AND_ASSIGN(Socket); }; Loading
fastboot/socket_mock.cpp +20 −11 Original line number Diff line number Diff line Loading @@ -38,26 +38,35 @@ SocketMock::~SocketMock() { } } ssize_t SocketMock::Send(const void* data, size_t length) { bool SocketMock::Send(const void* data, size_t length) { if (events_.empty()) { ADD_FAILURE() << "Send() was called when no message was expected"; return -1; return false; } if (events_.front().type != EventType::kSend) { ADD_FAILURE() << "Send() was called out-of-order"; return -1; return false; } std::string message(reinterpret_cast<const char*>(data), length); if (events_.front().message != message) { ADD_FAILURE() << "Send() expected " << events_.front().message << ", but got " << message; return -1; return false; } ssize_t return_value = events_.front().return_value; events_.pop(); return return_value; return true; } // Mock out multi-buffer send to be one large send, since that's what it should looks like from // the user's perspective. bool SocketMock::Send(std::vector<cutils_socket_buffer_t> buffers) { std::string data; for (const auto& buffer : buffers) { data.append(reinterpret_cast<const char*>(buffer.data), buffer.length); } return Send(data.data(), data.size()); } ssize_t SocketMock::Receive(void* data, size_t length, int /*timeout_ms*/) { Loading Loading @@ -106,13 +115,13 @@ std::unique_ptr<Socket> SocketMock::Accept() { } void SocketMock::ExpectSend(std::string message) { ssize_t return_value = message.length(); events_.push(Event(EventType::kSend, std::move(message), return_value, nullptr)); events_.push(Event(EventType::kSend, std::move(message), 0, nullptr)); } void SocketMock::ExpectSendFailure(std::string message) { events_.push(Event(EventType::kSend, std::move(message), -1, nullptr)); } // TODO: make this properly return false to the caller. //void SocketMock::ExpectSendFailure(std::string message) { // events_.push(Event(EventType::kSend, std::move(message), 0, nullptr)); //} void SocketMock::AddReceive(std::string message) { ssize_t return_value = message.length(); Loading
fastboot/socket_mock.h +2 −4 Original line number Diff line number Diff line Loading @@ -56,7 +56,8 @@ class SocketMock : public Socket { SocketMock(); ~SocketMock() override; ssize_t Send(const void* data, size_t length) override; bool Send(const void* data, size_t length) override; bool Send(std::vector<cutils_socket_buffer_t> buffers) override; ssize_t Receive(void* data, size_t length, int timeout_ms) override; int Close() override; virtual std::unique_ptr<Socket> Accept(); Loading @@ -64,9 +65,6 @@ class SocketMock : public Socket { // Adds an expectation for Send(). void ExpectSend(std::string message); // Adds an expectation for Send() that returns -1. void ExpectSendFailure(std::string message); // Adds data to provide for Receive(). void AddReceive(std::string message); Loading