1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "tools/android/common/adb_connection.h" 6 7 #include <arpa/inet.h> 8 #include <errno.h> 9 #include <stdio.h> 10 #include <stdlib.h> 11 #include <sys/socket.h> 12 #include <sys/types.h> 13 #include <unistd.h> 14 15 #include "base/logging.h" 16 #include "base/posix/eintr_wrapper.h" 17 #include "tools/android/common/net.h" 18 19 namespace tools { 20 namespace { 21 22 void CloseSocket(int fd) { 23 if (fd >= 0) { 24 int old_errno = errno; 25 close(fd); 26 errno = old_errno; 27 } 28 } 29 30 } // namespace 31 32 int ConnectAdbHostSocket(const char* forward_to) { 33 // ADB port forward request format: HHHHtcp:port:address. 34 // HHHH is the hexidecimal length of the "tcp:port:address" part. 35 const size_t kBufferMaxLength = 30; 36 const size_t kLengthOfLength = 4; 37 const size_t kAddressMaxLength = kBufferMaxLength - kLengthOfLength; 38 39 const char kAddressPrefix[] = { 't', 'c', 'p', ':' }; 40 size_t address_length = arraysize(kAddressPrefix) + strlen(forward_to); 41 if (address_length > kBufferMaxLength - kLengthOfLength) { 42 LOG(ERROR) << "Forward to address is too long: " << forward_to; 43 return -1; 44 } 45 46 char request[kBufferMaxLength]; 47 memcpy(request + kLengthOfLength, kAddressPrefix, arraysize(kAddressPrefix)); 48 memcpy(request + kLengthOfLength + arraysize(kAddressPrefix), 49 forward_to, strlen(forward_to)); 50 51 char length_buffer[kLengthOfLength + 1]; 52 snprintf(length_buffer, arraysize(length_buffer), "%04X", 53 static_cast<int>(address_length)); 54 memcpy(request, length_buffer, kLengthOfLength); 55 56 int host_socket = socket(AF_INET, SOCK_STREAM, 0); 57 if (host_socket < 0) { 58 LOG(ERROR) << "Failed to create adb socket: " << strerror(errno); 59 return -1; 60 } 61 62 DisableNagle(host_socket); 63 64 const int kAdbPort = 5037; 65 sockaddr_in addr; 66 memset(&addr, 0, sizeof(addr)); 67 addr.sin_family = AF_INET; 68 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); 69 addr.sin_port = htons(kAdbPort); 70 if (HANDLE_EINTR(connect(host_socket, reinterpret_cast<sockaddr*>(&addr), 71 sizeof(addr))) < 0) { 72 LOG(ERROR) << "Failed to connect adb socket: " << strerror(errno); 73 CloseSocket(host_socket); 74 return -1; 75 } 76 77 size_t bytes_remaining = address_length + kLengthOfLength; 78 size_t bytes_sent = 0; 79 while (bytes_remaining > 0) { 80 int ret = HANDLE_EINTR(send(host_socket, request + bytes_sent, 81 bytes_remaining, 0)); 82 if (ret < 0) { 83 LOG(ERROR) << "Failed to send request: " << strerror(errno); 84 CloseSocket(host_socket); 85 return -1; 86 } 87 88 bytes_sent += ret; 89 bytes_remaining -= ret; 90 } 91 92 const size_t kAdbStatusLength = 4; 93 char response[kBufferMaxLength]; 94 int response_length = HANDLE_EINTR(recv(host_socket, response, 95 kBufferMaxLength, 0)); 96 if (response_length < kAdbStatusLength || 97 strncmp("OKAY", response, kAdbStatusLength) != 0) { 98 LOG(ERROR) << "Bad response from ADB: length: " << response_length 99 << " data: " << DumpBinary(response, response_length); 100 CloseSocket(host_socket); 101 return -1; 102 } 103 104 return host_socket; 105 } 106 107 } // namespace tools 108