1d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine/* Copyright (C) 2006-2010 The Android Open Source Project
2d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine**
3d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** This software is licensed under the terms of the GNU General Public
4d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** License version 2, as published by the Free Software Foundation, and
5d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** may be copied, distributed, and modified under those terms.
6d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine**
7d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** This program is distributed in the hope that it will be useful,
8d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** but WITHOUT ANY WARRANTY; without even the implied warranty of
9d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine** GNU General Public License for more details.
11d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine*/
12d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
13d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "libslirp.h"
14d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "qemu-common.h"
15d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "sysemu.h"
16d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "modem_driver.h"
17d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "proxy_http.h"
18d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
19d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/android.h"
20d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/globals.h"
21d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/hw-sensors.h"
22d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/utils/debug.h"
23d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/utils/path.h"
24d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/utils/system.h"
25d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#include "android/utils/bufprint.h"
26d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/adb-server.h"
27d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine#include "android/adb-qemud.h"
28d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
29d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#define  D(...)  do {  if (VERBOSE_CHECK(init)) dprint(__VA_ARGS__); } while (0)
30d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
31d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#ifdef ANDROID_SDK_TOOLS_REVISION
32d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#  define  VERSION_STRING  STRINGIFY(ANDROID_SDK_TOOLS_REVISION)".0"
33d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#else
34d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#  define  VERSION_STRING  "standalone"
35d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#endif
36d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
37d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkineextern int  control_console_start( int  port );  /* in control.c */
38d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
39d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine/* Contains arguments for -android-ports option. */
40d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkinechar* android_op_ports = NULL;
41d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine/* Contains arguments for -android-port option. */
42d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkinechar* android_op_port = NULL;
43d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine/* Contains arguments for -android-report-console option. */
44d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkinechar* android_op_report_console = NULL;
45d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine/* Contains arguments for -http-proxy option. */
46d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkinechar* op_http_proxy = NULL;
472fa5173bd1ce7341c50adac676a317945f0969c7Vladimir Chtchetkine/* Base port for the emulated system. */
482fa5173bd1ce7341c50adac676a317945f0969c7Vladimir Chtchetkineint    android_base_port;
49d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine
50733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall/* Strings describing the host system's OpenGL implementation */
51733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallchar android_gl_vendor[ANDROID_GLSTRING_BUF_SIZE];
52733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallchar android_gl_renderer[ANDROID_GLSTRING_BUF_SIZE];
53733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hallchar android_gl_version[ANDROID_GLSTRING_BUF_SIZE];
54733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall
55d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine/*** APPLICATION DIRECTORY
56d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine *** Where are we ?
57d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine ***/
58d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
59d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkineconst char*  get_app_dir(void)
60d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine{
61d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    char  buffer[1024];
62d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    char* p   = buffer;
63d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    char* end = p + sizeof(buffer);
64d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    p = bufprint_app_dir(p, end);
65d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (p >= end)
66d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        return NULL;
67d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
68d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    return strdup(buffer);
69d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine}
70d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
71d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkineenum {
72d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    REPORT_CONSOLE_SERVER = (1 << 0),
73d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    REPORT_CONSOLE_MAX    = (1 << 1)
74d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine};
75d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
76d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkinestatic int
77d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkineget_report_console_options( char*  end, int  *maxtries )
78d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine{
79d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int    flags = 0;
80d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
81d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (end == NULL || *end == 0)
82d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        return 0;
83d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
84d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (end[0] != ',') {
85d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        derror( "socket port/path can be followed by [,<option>]+ only\n");
86d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        exit(3);
87d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
88d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    end += 1;
89d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    while (*end) {
90d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*  p = strchr(end, ',');
91d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (p == NULL)
92d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            p = end + strlen(end);
93d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
94d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (memcmp( end, "server", p-end ) == 0)
95d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            flags |= REPORT_CONSOLE_SERVER;
96d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        else if (memcmp( end, "max=", 4) == 0) {
97d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            end  += 4;
98d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            *maxtries = strtol( end, NULL, 10 );
99d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            flags |= REPORT_CONSOLE_MAX;
100d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        } else {
101d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            derror( "socket port/path can be followed by [,server][,max=<count>] only\n");
102d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(3);
103d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
104d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
105d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        end = p;
106d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (*end)
107d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            end += 1;
108d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
109d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    return flags;
110d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine}
111d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
112d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkinestatic void
113d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkinereport_console( const char*  proto_port, int  console_port )
114d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine{
115d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   s = -1, s2;
116d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   maxtries = 10;
117d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   flags = 0;
118d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    signal_state_t  sigstate;
119d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
120d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    disable_sigalrm( &sigstate );
121d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
122d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if ( !strncmp( proto_port, "tcp:", 4) ) {
123d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*  end;
124d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        long   port = strtol(proto_port + 4, &end, 10);
125d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
126d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        flags = get_report_console_options( end, &maxtries );
127d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
128d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (flags & REPORT_CONSOLE_SERVER) {
129d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            s = socket_loopback_server( port, SOCKET_STREAM );
130d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (s < 0) {
131d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                fprintf(stderr, "could not create server socket on TCP:%ld: %s\n",
132d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                        port, errno_str);
133d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                exit(3);
134d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
135d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        } else {
136d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            for ( ; maxtries > 0; maxtries-- ) {
137d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                D("trying to find console-report client on tcp:%d", port);
138d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                s = socket_loopback_client( port, SOCKET_STREAM );
139d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                if (s >= 0)
140d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    break;
141d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
142d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                sleep_ms(1000);
143d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
144d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (s < 0) {
145d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                fprintf(stderr, "could not connect to server on TCP:%ld: %s\n",
146d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                        port, errno_str);
147d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                exit(3);
148d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
149d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
150d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    } else if ( !strncmp( proto_port, "unix:", 5) ) {
151d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#ifdef _WIN32
152d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        fprintf(stderr, "sorry, the unix: protocol is not supported on Win32\n");
153d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        exit(3);
154d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#else
155d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*  path = strdup(proto_port+5);
156d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*  end  = strchr(path, ',');
157d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (end != NULL) {
158d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            flags = get_report_console_options( end, &maxtries );
159d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            *end  = 0;
160d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
161d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (flags & REPORT_CONSOLE_SERVER) {
162d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            s = socket_unix_server( path, SOCKET_STREAM );
163d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (s < 0) {
164d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                fprintf(stderr, "could not bind unix socket on '%s': %s\n",
165d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                        proto_port+5, errno_str);
166d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                exit(3);
167d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
168d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        } else {
169d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            for ( ; maxtries > 0; maxtries-- ) {
170d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                s = socket_unix_client( path, SOCKET_STREAM );
171d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                if (s >= 0)
172d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    break;
173d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
174d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                sleep_ms(1000);
175d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
176d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (s < 0) {
177d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                fprintf(stderr, "could not connect to unix socket on '%s': %s\n",
178d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                        path, errno_str);
179d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                exit(3);
180d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
181d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
182d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        free(path);
183d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#endif
184d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    } else {
185d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        fprintf(stderr, "-report-console must be followed by a 'tcp:<port>' or 'unix:<path>'\n");
186d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        exit(3);
187d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
188d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
189d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (flags & REPORT_CONSOLE_SERVER) {
190d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        int  tries = 3;
191d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        D( "waiting for console-reporting client" );
192d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        do {
193d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            s2 = socket_accept(s, NULL);
194d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        } while (s2 < 0 && --tries > 0);
195d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
196d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (s2 < 0) {
197d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            fprintf(stderr, "could not accept console-reporting client connection: %s\n",
198d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                   errno_str);
199d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(3);
200d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
201d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
202d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        socket_close(s);
203d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        s = s2;
204d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
205d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
206d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    /* simply send the console port in text */
207d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    {
208d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char  temp[12];
209d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        snprintf( temp, sizeof(temp), "%d", console_port );
210d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
211d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (socket_send(s, temp, strlen(temp)) < 0) {
212d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            fprintf(stderr, "could not send console number report: %d: %s\n",
213d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    errno, errno_str );
214d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(3);
215d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
216d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        socket_close(s);
217d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
218d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    D( "console port number sent to remote. resuming boot" );
219d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
220d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    restore_sigalrm (&sigstate);
221d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine}
222d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
223d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine/* this function is called from qemu_main() once all arguments have been parsed
224d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine * it should be used to setup any Android-specific items in the emulation before the
225d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine * main loop runs
226d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine */
227d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkinevoid  android_emulation_setup( void )
228d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine{
229d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   tries     = 16;
230d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   base_port = 5554;
231d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   adb_host_port = 5037; // adb's default
232d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   success   = 0;
233d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    int   s;
234d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    uint32_t  guest_ip;
235d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
236d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        /* Set the port where the emulator expects adb to run on the host
237d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine         * machine */
238d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    char* adb_host_port_str = getenv( "ANDROID_ADB_SERVER_PORT" );
239d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if ( adb_host_port_str && strlen( adb_host_port_str ) > 0 ) {
240d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        adb_host_port = (int) strtol( adb_host_port_str, NULL, 0 );
241d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( adb_host_port <= 0 ) {
242d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            derror( "env var ANDROID_ADB_SERVER_PORT must be a number > 0. Got \"%s\"\n",
243d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    adb_host_port_str );
244d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(1);
245d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
246d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
247d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
248d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    inet_strtoip("10.0.2.15", &guest_ip);
249d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
250d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#if 0
251d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (opts->adb_port) {
252d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        fprintf( stderr, "option -adb-port is obsolete, use -port instead\n" );
253d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        exit(1);
254d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
255d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#endif
256d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
257d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (android_op_port && android_op_ports) {
258d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        fprintf( stderr, "options -port and -ports cannot be used together.\n");
259d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        exit(1);
260d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
261d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
262d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine    int legacy_adb = avdInfo_getAdbdCommunicationMode(android_avdInfo) ? 0 : 1;
263d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine
264d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (android_op_ports) {
265d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char* comma_location;
266d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char* end;
267d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        int console_port = strtol( android_op_ports, &comma_location, 0 );
268d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
269d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( comma_location == NULL || *comma_location != ',' ) {
270d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            derror( "option -ports must be followed by two comma separated positive integer numbers" );
271d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(1);
272d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
273d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
274d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        int adb_port = strtol( comma_location+1, &end, 0 );
275d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
276d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( end == NULL || *end ) {
277d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            derror( "option -ports must be followed by two comma separated positive integer numbers" );
278d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(1);
279d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
280d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
281d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( console_port == adb_port ) {
282d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            derror( "option -ports must be followed by two different integer numbers" );
283d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(1);
284d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
285d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
286d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        // Set up redirect from host to guest system. adbd on the guest listens
287d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        // on 5555.
288d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        if (legacy_adb) {
289d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            slirp_redir( 0, adb_port, guest_ip, 5555 );
290d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        } else {
291d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            adb_server_init(adb_port);
292d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            android_adb_service_init();
293d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine        }
294d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( control_console_start( console_port ) < 0 ) {
295d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            if (legacy_adb) {
296d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                slirp_unredir( 0, adb_port );
297d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            }
298d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
299d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
300d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        base_port = console_port;
301d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    } else {
302d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        if (android_op_port) {
303d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            char*  end;
304d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine            int    port = strtol( android_op_port, &end, 0 );
305d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if ( end == NULL || *end ||
306d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                (unsigned)((port - base_port) >> 1) >= (unsigned)tries ) {
307d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                derror( "option -port must be followed by an even integer number between %d and %d\n",
308d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                        base_port, base_port + (tries-1)*2 );
309d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                exit(1);
310d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
311d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if ( (port & 1) != 0 ) {
312d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                port &= ~1;
313d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                dwarning( "option -port must be followed by an even integer, using  port number %d\n",
314d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                          port );
315d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
316d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            base_port = port;
317d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            tries     = 1;
318d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
319d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
320d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        for ( ; tries > 0; tries--, base_port += 2 ) {
321d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
322d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            /* setup first redirection for ADB, the Android Debug Bridge */
323d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            if (legacy_adb) {
324d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                if ( slirp_redir( 0, base_port+1, guest_ip, 5555 ) < 0 )
325d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    continue;
326d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            } else {
327d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                if (adb_server_init(base_port+1))
328d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    continue;
329d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                android_adb_service_init();
330d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine            }
331d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
332d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            /* setup second redirection for the emulator console */
333d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if ( control_console_start( base_port ) < 0 ) {
334d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                if (legacy_adb) {
335d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                    slirp_unredir( 0, base_port+1 );
336d86c724b74e6c04a89219d87559d0b580e100445Vladimir Chtchetkine                }
337d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                continue;
338d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
339d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
340d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            D( "control console listening on port %d, ADB on port %d", base_port, base_port+1 );
341d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            success = 1;
342d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            break;
343d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
344d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
345d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (!success) {
346d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            fprintf(stderr, "it seems too many emulator instances are running on this machine. Aborting\n" );
347d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            exit(1);
348d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
349d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
350d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
351d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (android_op_report_console) {
352d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        report_console(android_op_report_console, base_port);
353d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
354d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
355d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    android_modem_init( base_port );
356d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
3575758404ffd1be160efa303ff27eef645fc4e2c2dVladimir Chtchetkine    /* Save base port. */
358cefa7443eb3d3e4bb134595f756145426d5613e3Vladimir Chtchetkine    android_base_port = base_port;
3593cf34f28ff198c69a02ed74a8e851b53cf3ff00cDavid 'Digit' Turner
360d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine   /* send a simple message to the ADB host server to tell it we just started.
361d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    * it should be listening on port 5037. if we can't reach it, don't bother
362d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    */
363d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    do
364d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    {
365d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        SockAddress  addr;
366d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char         tmp[32];
367d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
368d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        s = socket_create_inet( SOCKET_STREAM );
369d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (s < 0) {
370d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            D("can't create socket to talk to the ADB server");
371d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            break;
372d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
373d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
374d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        sock_address_init_inet( &addr, SOCK_ADDRESS_INET_LOOPBACK, adb_host_port );
375d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (socket_connect( s, &addr ) < 0) {
376d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            D("can't connect to ADB server: %s", errno_str );
377d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            break;
378d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
379d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
380d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        sprintf(tmp,"0012host:emulator:%d",base_port+1);
381d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        socket_send(s, tmp, 18+4);
382d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        D("sent '%s' to ADB server", tmp);
383d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
384d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    while (0);
385d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
386d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (s >= 0)
387d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        socket_close(s);
388d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
389d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    /* setup the http proxy, if any */
390d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    if (VERBOSE_CHECK(proxy))
391d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        proxy_set_verbose(1);
392d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
393d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine    if (!op_http_proxy) {
394d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        op_http_proxy = getenv("http_proxy");
395d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
396d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
397d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    do
398d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    {
399d81e6d1ce722d7e561d495bbd4b137e728e25b83Vladimir Chtchetkine        const char*  env = op_http_proxy;
400d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        int          envlen;
401d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        ProxyOption  option_tab[4];
402d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        ProxyOption* option = option_tab;
403d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*        p;
404d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char*        q;
405d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        const char*  proxy_name;
406d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        int          proxy_name_len;
407d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        int          proxy_port;
408d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
409d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (!env)
410d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            break;
411d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
412d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        envlen = strlen(env);
413d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
414d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        /* skip the 'http://' header, if present */
415d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (envlen >= 7 && !memcmp(env, "http://", 7)) {
416d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            env    += 7;
417d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            envlen -= 7;
418d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
419d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
420d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        /* do we have a username:password pair ? */
421d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        p = strchr(env, '@');
422d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (p != 0) {
423d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            q = strchr(env, ':');
424d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (q == NULL) {
425d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            BadHttpProxyFormat:
426d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                dprint("http_proxy format unsupported, try 'proxy:port' or 'username:password@proxy:port'");
427d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                break;
428d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
429d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
430d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->type       = PROXY_OPTION_AUTH_USERNAME;
431d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->string     = env;
432d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->string_len = q - env;
433d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option++;
434d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
435d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->type       = PROXY_OPTION_AUTH_PASSWORD;
436d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->string     = q+1;
437d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option->string_len = p - (q+1);
438d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            option++;
439d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
440d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            env = p+1;
441d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
442d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
443d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        p = strchr(env,':');
444d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (p == NULL)
445d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            goto BadHttpProxyFormat;
446d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
447d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        proxy_name     = env;
448d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        proxy_name_len = p - env;
449d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        proxy_port     = atoi(p+1);
450d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
451d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        D( "setting up http proxy:  server=%.*s port=%d",
452d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                proxy_name_len, proxy_name, proxy_port );
453d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
4549b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        /* Check that we can connect to the proxy in the next second.
4559b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner         * If not, the proxy setting is probably garbage !!
4569b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner         */
4579b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        if ( proxy_check_connection( proxy_name, proxy_name_len, proxy_port, 1000 ) < 0) {
4589b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner            dprint("Could not connect to proxy at %.*s:%d: %s !",
4599b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner                   proxy_name_len, proxy_name, proxy_port, errno_str);
4609b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner            dprint("Proxy will be ignored !");
4619b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner            break;
4629b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner        }
4639b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner
464d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if ( proxy_http_setup( proxy_name, proxy_name_len, proxy_port,
465d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                               option - option_tab, option_tab ) < 0 )
466d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        {
4679b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner            dprint( "Http proxy setup failed for '%.*s:%d': %s",
4689b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner                    proxy_name_len, proxy_name, proxy_port, errno_str);
4699b98dbde344781e93e2bdcfa599428cda2fda41dDavid 'Digit' Turner            dprint( "Proxy will be ignored !");
470d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
471d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
472d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    while (0);
473d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
474d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    /* initialize sensors, this must be done here due to timer issues */
475d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    android_hw_sensors_init();
476d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
477d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine   /* cool, now try to run the "ddms ping" command, which will take care of pinging usage
478d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    * if the user agreed for it. the emulator itself never sends anything to any outside
479d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    * machine
480d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    */
481d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    {
482d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#ifdef _WIN32
483d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#  define  _ANDROID_PING_PROGRAM   "ddms.bat"
484d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#else
485d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#  define  _ANDROID_PING_PROGRAM   "ddms"
486d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#endif
487d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
488d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        char         tmp[PATH_MAX];
489d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        const char*  appdir = get_app_dir();
490d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
491733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall        const size_t ARGSLEN =
492733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                PATH_MAX +                    // max ping program path
493733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                10 +                          // max VERSION_STRING length
494733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                3*ANDROID_GLSTRING_BUF_SIZE + // max GL string lengths
495733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                29 +                          // static args characters
496733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                1;                            // NUL terminator
497733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall        char args[ARGSLEN];
498733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall
499d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (snprintf( tmp, PATH_MAX, "%s%s%s", appdir, PATH_SEP,
500d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                      _ANDROID_PING_PROGRAM ) >= PATH_MAX) {
501d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            dprint( "Application directory too long: %s", appdir);
502d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            return;
503d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
504d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
505d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        /* if the program isn't there, don't bother */
506d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        D( "ping program: %s", tmp);
507d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        if (path_exists(tmp)) {
508d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#ifdef _WIN32
509d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            STARTUPINFO           startup;
510d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            PROCESS_INFORMATION   pinfo;
511d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
512d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            ZeroMemory( &startup, sizeof(startup) );
513d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            startup.cb = sizeof(startup);
514d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            startup.dwFlags = STARTF_USESHOWWINDOW;
515d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            startup.wShowWindow = SW_SHOWMINIMIZED;
516d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
517d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            ZeroMemory( &pinfo, sizeof(pinfo) );
518d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
519d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            char* comspec = getenv("COMSPEC");
520d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            if (!comspec) comspec = "cmd.exe";
521d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
522d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            // Run
523733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall            if (snprintf(args, ARGSLEN,
524733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                    "/C \"%s\" ping emulator " VERSION_STRING " \"%s\" \"%s\" \"%s\"",
525733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                    tmp, android_gl_vendor, android_gl_renderer, android_gl_version)
526733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                >= ARGSLEN)
527733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall            {
528733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                D( "DDMS command line too long: %s", args);
529d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                return;
530d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            }
531d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
532d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            CreateProcess(
533d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                comspec,                                      /* program path */
534d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                args,                                    /* command line args */
535d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                NULL,                    /* process handle is not inheritable */
536d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                NULL,                     /* thread handle is not inheritable */
537d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                FALSE,                       /* no, don't inherit any handles */
538d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                DETACHED_PROCESS,   /* the new process doesn't have a console */
539d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                NULL,                       /* use parent's environment block */
540d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                NULL,                      /* use parent's starting directory */
541d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                &startup,                   /* startup info, i.e. std handles */
542d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                &pinfo );
543d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
544d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            D( "ping command: %s %s", comspec, args );
545d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#else
546d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            int  pid;
547d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
548d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            /* disable SIGALRM for the fork(), the periodic signal seems to
549d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine             * interefere badly with the fork() implementation on Linux running
550d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine             * under VMWare.
551d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine             */
552d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            BEGIN_NOSIGALRM
553d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                pid = fork();
554d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                if (pid == 0) {
555d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    int  fd = open("/dev/null", O_WRONLY);
556d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    dup2(fd, 1);
557d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                    dup2(fd, 2);
558733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                    execl( tmp, _ANDROID_PING_PROGRAM, "ping", "emulator", VERSION_STRING,
559733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                            android_gl_vendor, android_gl_renderer, android_gl_version,
560733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                            NULL );
561d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine                }
562d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            END_NOSIGALRM
563d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
564d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine            /* don't do anything in the parent or in case of error */
565733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall            snprintf(args, ARGSLEN,
566733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                    "%s ping emulator " VERSION_STRING " \"%s\" \"%s\" \"%s\"",
567733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall                    tmp, android_gl_vendor, android_gl_renderer, android_gl_version);
568733fffaac9ccebfc424fccf9467b22475f71a2f8Jesse Hall            D( "ping command: %s", args );
569d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine#endif
570d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine        }
571d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine    }
572d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine}
573d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
574d27aca1c8172462c6e834c3c42582106b36aa422Vladimir Chtchetkine
575