Home | History | Annotate | Download | only in client
      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