/* * Copyright 2008, The Android Open Source Project * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #define LOG_TAG "wdsclient" #include "AdbConnection.h" #include "ClientUtils.h" #include "Device.h" #include #include #include #include #include #include #include #include #define DEFAULT_WDS_PORT 9999 #define STR(x) #x #define XSTR(x) STR(x) #define PORT_STR XSTR(DEFAULT_WDS_PORT) int wds_open() { // Create the structure for connecting to the forwarded 9999 port sockaddr_in addr; createTcpSocket(addr, DEFAULT_WDS_PORT); // Create our socket int fd = socket(PF_INET, SOCK_STREAM, 0); if (fd < 0) { log_errno("Failed to create file descriptor"); return -1; } // Connect to the remote wds server thread if (connect(fd, (sockaddr*)&addr, sizeof(addr)) < 0) { log_errno("Failed to connect to remote debug server"); return -1; } return fd; } // Clean up the file descriptor and connections void wds_close(int fd) { if (fd != -1) { shutdown(fd, SHUT_RDWR); close(fd); } } int main(int argc, char** argv) { Device::DeviceType type = Device::NONE; if (argc <= 1) { ALOGE("wdsclient takes at least 1 argument"); return 1; } else { // Parse the options, look for -e or -d to choose a device. while (true) { int c = getopt(argc, argv, "ed"); if (c == -1) break; switch (c) { case 'e': type = Device::EMULATOR; break; case 'd': type = Device::DEVICE; break; default: break; } } if (optind == argc) { ALOGE("No command specified"); return 1; } } // Do the initial connection. AdbConnection conn; conn.connect(); const DeviceList& devices = conn.getDeviceList(); // host:devices closes the connection, reconnect conn.connect(); // No device specified and more than one connected, bail if (type == Device::NONE && devices.size() > 1) { ALOGE("More than one device/emulator, please specify with -e or -d"); return 1; } else if (devices.size() == 0) { ALOGE("No devices connected"); return 1; } // Find the correct device const Device* device = NULL; if (type == Device::NONE) device = devices[0]; // grab the only one else { // Search for a matching device type for (unsigned i = 0; i < devices.size(); i++) { if (devices[i]->type() == type) { device = devices[i]; break; } } } if (!device) { ALOGE("No device found!"); return 1; } // Forward tcp:9999 if (!device->sendRequest("forward:tcp:" PORT_STR ";tcp:" PORT_STR)) { ALOGE("Failed to send forwarding request"); return 1; } ALOGV("Connecting to localhost port " PORT_STR); const char* command = argv[optind]; int commandLen = strlen(command); #define WDS_COMMAND_LENGTH 4 if (commandLen != WDS_COMMAND_LENGTH) { ALOGE("Commands must be 4 characters '%s'", command); return 1; } // Open the wds connection int wdsFd = wds_open(); if (wdsFd == -1) return 1; // Send the command specified send(wdsFd, command, WDS_COMMAND_LENGTH, 0); // commands are 4 bytes // Read and display the response char response[256]; int res = 0; while ((res = recv(wdsFd, response, sizeof(response), 0)) > 0) printf("%.*s", res, response); printf("\n\n"); // Shutdown wds_close(wdsFd); return 0; }