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
wds_open()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
wds_close(int fd)65 void wds_close(int fd) {
66 if (fd != -1) {
67 shutdown(fd, SHUT_RDWR);
68 close(fd);
69 }
70 }
71
main(int argc,char ** argv)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