• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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