| /* |
| * 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 <arpa/inet.h> |
| #include <errno.h> |
| #include <getopt.h> |
| #include <stdlib.h> |
| #include <string.h> |
| #include <sys/socket.h> |
| #include <sys/types.h> |
| #include <utils/Log.h> |
| |
| #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; |
| } |