1 /* 2 * Copyright 2008, The Android Open Source Project 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * * Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * * Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #define LOG_TAG "wdsclient" 27 28 #include "AdbConnection.h" 29 #include "ClientUtils.h" 30 #include "Device.h" 31 #include <arpa/inet.h> 32 #include <errno.h> 33 #include <getopt.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <sys/socket.h> 37 #include <sys/types.h> 38 #include <utils/Log.h> 39 40 #define DEFAULT_WDS_PORT 9999 41 #define STR(x) #x 42 #define XSTR(x) STR(x) 43 #define PORT_STR XSTR(DEFAULT_WDS_PORT) 44 45 int wds_open() { 46 // Create the structure for connecting to the forwarded 9999 port 47 sockaddr_in addr; 48 createTcpSocket(addr, DEFAULT_WDS_PORT); 49 50 // Create our socket 51 int fd = socket(PF_INET, SOCK_STREAM, 0); 52 if (fd < 0) { 53 log_errno("Failed to create file descriptor"); 54 return -1; 55 } 56 // Connect to the remote wds server thread 57 if (connect(fd, (sockaddr*)&addr, sizeof(addr)) < 0) { 58 log_errno("Failed to connect to remote debug server"); 59 return -1; 60 } 61 return fd; 62 } 63 64 // Clean up the file descriptor and connections 65 void wds_close(int fd) { 66 if (fd != -1) { 67 shutdown(fd, SHUT_RDWR); 68 close(fd); 69 } 70 } 71 72 int main(int argc, char** argv) { 73 74 Device::DeviceType type = Device::NONE; 75 76 if (argc <= 1) { 77 LOGE("wdsclient takes at least 1 argument"); 78 return 1; 79 } else { 80 // Parse the options, look for -e or -d to choose a device. 81 while (true) { 82 int c = getopt(argc, argv, "ed"); 83 if (c == -1) 84 break; 85 switch (c) { 86 case 'e': 87 type = Device::EMULATOR; 88 break; 89 case 'd': 90 type = Device::DEVICE; 91 break; 92 default: 93 break; 94 } 95 } 96 if (optind == argc) { 97 LOGE("No command specified"); 98 return 1; 99 } 100 } 101 102 // Do the initial connection. 103 AdbConnection conn; 104 conn.connect(); 105 106 const DeviceList& devices = conn.getDeviceList(); 107 // host:devices closes the connection, reconnect 108 conn.connect(); 109 110 // No device specified and more than one connected, bail 111 if (type == Device::NONE && devices.size() > 1) { 112 LOGE("More than one device/emulator, please specify with -e or -d"); 113 return 1; 114 } else if (devices.size() == 0) { 115 LOGE("No devices connected"); 116 return 1; 117 } 118 119 // Find the correct device 120 const Device* device = NULL; 121 if (type == Device::NONE) 122 device = devices[0]; // grab the only one 123 else { 124 // Search for a matching device type 125 for (unsigned i = 0; i < devices.size(); i++) { 126 if (devices[i]->type() == type) { 127 device = devices[i]; 128 break; 129 } 130 } 131 } 132 133 if (!device) { 134 LOGE("No device found!"); 135 return 1; 136 } 137 138 // Forward tcp:9999 139 if (!device->sendRequest("forward:tcp:" PORT_STR ";tcp:" PORT_STR)) { 140 LOGE("Failed to send forwarding request"); 141 return 1; 142 } 143 144 LOGV("Connecting to localhost port " PORT_STR); 145 146 const char* command = argv[optind]; 147 int commandLen = strlen(command); 148 #define WDS_COMMAND_LENGTH 4 149 if (commandLen != WDS_COMMAND_LENGTH) { 150 LOGE("Commands must be 4 characters '%s'", command); 151 return 1; 152 } 153 154 // Open the wds connection 155 int wdsFd = wds_open(); 156 if (wdsFd == -1) 157 return 1; 158 159 // Send the command specified 160 send(wdsFd, command, WDS_COMMAND_LENGTH, 0); // commands are 4 bytes 161 162 // Read and display the response 163 char response[256]; 164 int res = 0; 165 while ((res = recv(wdsFd, response, sizeof(response), 0)) > 0) 166 printf("%.*s", res, response); 167 printf("\n\n"); 168 169 // Shutdown 170 wds_close(wdsFd); 171 172 return 0; 173 } 174