12ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell/* 22ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * Copyright (C) 2016 The Android Open Source Project 32ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * All rights reserved. 42ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * 52ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * Redistribution and use in source and binary forms, with or without 62ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * modification, are permitted provided that the following conditions 72ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * are met: 82ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * * Redistributions of source code must retain the above copyright 92ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * notice, this list of conditions and the following disclaimer. 102ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * * Redistributions in binary form must reproduce the above copyright 112ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * notice, this list of conditions and the following disclaimer in 122ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * the documentation and/or other materials provided with the 132ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * distribution. 142ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * 152ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 162ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 172ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 182ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 192ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 202ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 212ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 222ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 232ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 242ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 252ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 262ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell * SUCH DAMAGE. 272ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell */ 282ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 292ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell#include "tcp.h" 302ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 31aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell#include <android-base/parseint.h> 322ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell#include <android-base/stringprintf.h> 332ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 342ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellnamespace tcp { 352ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 362ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstatic constexpr int kProtocolVersion = 1; 372ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstatic constexpr size_t kHandshakeLength = 4; 382ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstatic constexpr int kHandshakeTimeoutMs = 2000; 392ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 402ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell// Extract the big-endian 8-byte message length into a 64-bit number. 412ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstatic uint64_t ExtractMessageLength(const void* buffer) { 422ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell uint64_t ret = 0; 432ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell for (int i = 0; i < 8; ++i) { 442ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell ret |= uint64_t{reinterpret_cast<const uint8_t*>(buffer)[i]} << (56 - i * 8); 452ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 462ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return ret; 472ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 482ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 492ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell// Encode the 64-bit number into a big-endian 8-byte message length. 502ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstatic void EncodeMessageLength(uint64_t length, void* buffer) { 512ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell for (int i = 0; i < 8; ++i) { 522ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell reinterpret_cast<uint8_t*>(buffer)[i] = length >> (56 - i * 8); 532ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 542ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 552ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 562ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellclass TcpTransport : public Transport { 572ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell public: 582ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // Factory function so we can return nullptr if initialization fails. 592ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell static std::unique_ptr<TcpTransport> NewTransport(std::unique_ptr<Socket> socket, 602ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell std::string* error); 612ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 622ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell ~TcpTransport() override = default; 632ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 642ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell ssize_t Read(void* data, size_t length) override; 652ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell ssize_t Write(const void* data, size_t length) override; 662ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell int Close() override; 672ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 682ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell private: 691c563d96f000876d77b2d33fbfb03c241bc503e1Chih-Hung Hsieh explicit TcpTransport(std::unique_ptr<Socket> sock) : socket_(std::move(sock)) {} 702ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 712ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // Connects to the device and performs the initial handshake. Returns false and fills |error| 722ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // on failure. 732ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell bool InitializeProtocol(std::string* error); 742ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 752ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell std::unique_ptr<Socket> socket_; 762ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell uint64_t message_bytes_left_ = 0; 772ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 782ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell DISALLOW_COPY_AND_ASSIGN(TcpTransport); 792ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell}; 802ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 812ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstd::unique_ptr<TcpTransport> TcpTransport::NewTransport(std::unique_ptr<Socket> socket, 822ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell std::string* error) { 832ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell std::unique_ptr<TcpTransport> transport(new TcpTransport(std::move(socket))); 842ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 852ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (!transport->InitializeProtocol(error)) { 862ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return nullptr; 872ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 882ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 892ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return transport; 902ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 912ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 922ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell// These error strings are checked in tcp_test.cpp and should be kept in sync. 932ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellbool TcpTransport::InitializeProtocol(std::string* error) { 942ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell std::string handshake_message(android::base::StringPrintf("FB%02d", kProtocolVersion)); 952ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 962ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (!socket_->Send(handshake_message.c_str(), kHandshakeLength)) { 972ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell *error = android::base::StringPrintf("Failed to send initialization message (%s)", 982ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell Socket::GetErrorMessage().c_str()); 992ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return false; 1002ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1012ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 102aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell char buffer[kHandshakeLength + 1]; 103aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell buffer[kHandshakeLength] = '\0'; 1042ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (socket_->ReceiveAll(buffer, kHandshakeLength, kHandshakeTimeoutMs) != kHandshakeLength) { 1052ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell *error = android::base::StringPrintf( 1062ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell "No initialization message received (%s). Target may not support TCP fastboot", 1072ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell Socket::GetErrorMessage().c_str()); 1082ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return false; 1092ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1102ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1112ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (memcmp(buffer, "FB", 2) != 0) { 1122ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell *error = "Unrecognized initialization message. Target may not support TCP fastboot"; 1132ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return false; 1142ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1152ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 116aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell int version = 0; 117aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell if (!android::base::ParseInt(buffer + 2, &version) || version < kProtocolVersion) { 1182ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell *error = android::base::StringPrintf("Unknown TCP protocol version %s (host version %02d)", 119aad72a533f97e8be5114e127fb681ee1596bdc89David Pursell buffer + 2, kProtocolVersion); 1202ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return false; 1212ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1222ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1232ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell error->clear(); 1242ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return true; 1252ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1262ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1272ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellssize_t TcpTransport::Read(void* data, size_t length) { 1282ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (socket_ == nullptr) { 1292ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return -1; 1302ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1312ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1322ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // Unless we're mid-message, read the next 8-byte message length. 1332ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (message_bytes_left_ == 0) { 1342ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell char buffer[8]; 1352ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (socket_->ReceiveAll(buffer, 8, 0) != 8) { 1362ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell Close(); 1372ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return -1; 1382ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1392ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell message_bytes_left_ = ExtractMessageLength(buffer); 1402ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1412ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1422ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // Now read the message (up to |length| bytes). 1432ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (length > message_bytes_left_) { 1442ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell length = message_bytes_left_; 1452ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1462ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell ssize_t bytes_read = socket_->ReceiveAll(data, length, 0); 1472ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (bytes_read == -1) { 1482ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell Close(); 1492ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } else { 1502ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell message_bytes_left_ -= bytes_read; 1512ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1522ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return bytes_read; 1532ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1542ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1552ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellssize_t TcpTransport::Write(const void* data, size_t length) { 1562ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (socket_ == nullptr) { 1572ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return -1; 1582ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1592ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1602ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // Use multi-buffer writes for better performance. 1612ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell char header[8]; 1622ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell EncodeMessageLength(length, header); 1632ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (!socket_->Send(std::vector<cutils_socket_buffer_t>{{header, 8}, {data, length}})) { 1642ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell Close(); 1652ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return -1; 1662ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1672ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1682ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return length; 1692ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1702ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1712ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellint TcpTransport::Close() { 1722ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (socket_ == nullptr) { 1732ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return 0; 1742ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1752ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1762ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell int result = socket_->Close(); 1772ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell socket_.reset(); 1782ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return result; 1792ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1802ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1812ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstd::unique_ptr<Transport> Connect(const std::string& hostname, int port, std::string* error) { 1822ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return internal::Connect(Socket::NewClient(Socket::Protocol::kTcp, hostname, port, error), 1832ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell error); 1842ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1852ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1862ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellnamespace internal { 1872ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1882ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursellstd::unique_ptr<Transport> Connect(std::unique_ptr<Socket> sock, std::string* error) { 1892ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell if (sock == nullptr) { 1902ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell // If Socket creation failed |error| is already set. 1912ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return nullptr; 1922ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell } 1932ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1942ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell return TcpTransport::NewTransport(std::move(sock), error); 1952ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} 1962ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1972ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} // namespace internal 1982ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell 1992ec418a4c98f6e8f95395456e1ad4c2956cac007David Pursell} // namespace tcp 200