1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/* This file implements the 'tcp:' goldfish pipe type which allows
18 * guest clients to directly connect to a TCP port through /dev/qemu_pipe.
19 */
20
21#include "sockets.h"
22#include "android/utils/assert.h"
23#include "android/utils/panic.h"
24#include "android/utils/system.h"
25#include "android/async-utils.h"
26#include "android/opengles.h"
27#include "android/looper.h"
28#include "hw/goldfish_pipe.h"
29
30/* Implement the OpenGL fast-pipe */
31
32/* Set to 1 or 2 for debug traces */
33// #define  DEBUG  1
34
35#if DEBUG >= 1
36#  define D(...)   printf(__VA_ARGS__), printf("\n")
37#else
38#  define D(...)   ((void)0)
39#endif
40
41#if DEBUG >= 2
42#  define DD(...)                       printf(__VA_ARGS__), printf("\n")
43#  define DDASSERT(cond)                _ANDROID_ASSERT(cond, "Assertion failure: ", #cond)
44#  define DDASSERT_INT_OP(cond,val,op)  _ANDROID_ASSERT_INT_OP(cond,val,op)
45#else
46#  define DD(...)                       ((void)0)
47#  define DDASSERT(cond)                ((void)0)
48#  define DDASSERT_INT_OP(cond,val,op)  ((void)0)
49#endif
50
51#define DDASSERT_INT_LT(cond,val)  DDASSERT_INT_OP(cond,val,<)
52#define DDASSERT_INT_LTE(cond,val)  DDASSERT_INT_OP(cond,val,<=)
53#define DDASSERT_INT_GT(cond,val)  DDASSERT_INT_OP(cond,val,>)
54#define DDASSERT_INT_GTE(cond,val)  DDASSERT_INT_OP(cond,val,>=)
55#define DDASSERT_INT_EQ(cond,val)  DDASSERT_INT_OP(cond,val,==)
56#define DDASSERT_INT_NEQ(cond,val)  DDASSERT_INT_OP(cond,val,!=)
57
58enum {
59    STATE_INIT,
60    STATE_CONNECTING,
61    STATE_CONNECTED,
62    STATE_CLOSING_GUEST,
63    STATE_CLOSING_SOCKET
64};
65
66typedef struct {
67    void*           hwpipe;
68    int             state;
69    int             wakeWanted;
70    LoopIo          io[1];
71    AsyncConnector  connector[1];
72} NetPipe;
73
74static void
75netPipe_free( NetPipe*  pipe )
76{
77    int  fd;
78
79    /* Close the socket */
80    fd = pipe->io->fd;
81    loopIo_done(pipe->io);
82    socket_close(fd);
83
84    /* Release the pipe object */
85    AFREE(pipe);
86}
87
88
89static void
90netPipe_resetState( NetPipe* pipe )
91{
92    if ((pipe->wakeWanted & PIPE_WAKE_WRITE) != 0) {
93        loopIo_wantWrite(pipe->io);
94    } else {
95        loopIo_dontWantWrite(pipe->io);
96    }
97
98   if (pipe->state == STATE_CONNECTED && (pipe->wakeWanted & PIPE_WAKE_READ) != 0) {
99        loopIo_wantRead(pipe->io);
100    } else {
101        loopIo_dontWantRead(pipe->io);
102    }
103}
104
105
106/* This function is only called when the socket is disconnected.
107 * See netPipe_closeFromGuest() for the case when the guest requires
108 * the disconnection. */
109static void
110netPipe_closeFromSocket( void* opaque )
111{
112    NetPipe*  pipe = opaque;
113
114    D("%s", __FUNCTION__);
115
116    /* If the guest already ordered the pipe to be closed, delete immediately */
117    if (pipe->state == STATE_CLOSING_GUEST) {
118        netPipe_free(pipe);
119        return;
120    }
121
122    /* Force the closure of the QEMUD channel - if a guest is blocked
123     * waiting for a wake signal, it will receive an error. */
124    if (pipe->hwpipe != NULL) {
125        goldfish_pipe_close(pipe->hwpipe);
126        pipe->hwpipe = NULL;
127    }
128
129    pipe->state = STATE_CLOSING_SOCKET;
130    netPipe_resetState(pipe);
131}
132
133
134/* This is the function that gets called each time there is an asynchronous
135 * event on the network pipe.
136 */
137static void
138netPipe_io_func( void* opaque, int fd, unsigned events )
139{
140    NetPipe*  pipe = opaque;
141    int         wakeFlags = 0;
142
143    /* Run the connector if we are in the CONNECTING state     */
144    /* TODO: Add some sort of time-out, to deal with the case */
145    /*        when the server is wedged.                      */
146    if (pipe->state == STATE_CONNECTING) {
147        AsyncStatus  status = asyncConnector_run(pipe->connector);
148        if (status == ASYNC_NEED_MORE) {
149            return;
150        }
151        else if (status == ASYNC_ERROR) {
152            /* Could not connect, tell our client by closing the channel. */
153
154            netPipe_closeFromSocket(pipe);
155            return;
156        }
157        pipe->state = STATE_CONNECTED;
158        netPipe_resetState(pipe);
159        return;
160    }
161
162    /* Otherwise, accept incoming data */
163    if ((events & LOOP_IO_READ) != 0) {
164        if ((pipe->wakeWanted & PIPE_WAKE_READ) != 0) {
165            wakeFlags |= PIPE_WAKE_READ;
166        }
167    }
168
169    if ((events & LOOP_IO_WRITE) != 0) {
170        if ((pipe->wakeWanted & PIPE_WAKE_WRITE) != 0) {
171            wakeFlags |= PIPE_WAKE_WRITE;
172        }
173    }
174
175    /* Send wake signal to the guest if needed */
176    if (wakeFlags != 0) {
177        goldfish_pipe_wake(pipe->hwpipe, wakeFlags);
178        pipe->wakeWanted &= ~wakeFlags;
179    }
180
181    /* Reset state */
182    netPipe_resetState(pipe);
183}
184
185
186void*
187netPipe_initFromAddress( void* hwpipe, const SockAddress*  address, Looper* looper )
188{
189    NetPipe*     pipe;
190
191    ANEW0(pipe);
192
193    pipe->hwpipe = hwpipe;
194    pipe->state  = STATE_INIT;
195
196    {
197        AsyncStatus  status;
198
199        int  fd = socket_create( sock_address_get_family(address), SOCKET_STREAM );
200        if (fd < 0) {
201            D("%s: Could create socket from address family!", __FUNCTION__);
202            netPipe_free(pipe);
203            return NULL;
204        }
205
206        loopIo_init(pipe->io, looper, fd, netPipe_io_func, pipe);
207        asyncConnector_init(pipe->connector, address, pipe->io);
208        pipe->state = STATE_CONNECTING;
209
210        status = asyncConnector_run(pipe->connector);
211        if (status == ASYNC_ERROR) {
212            D("%s: Could not connect to socket: %s",
213              __FUNCTION__, errno_str);
214            netPipe_free(pipe);
215            return NULL;
216        }
217        if (status == ASYNC_COMPLETE) {
218            pipe->state = STATE_CONNECTED;
219            netPipe_resetState(pipe);
220        }
221    }
222
223    return pipe;
224}
225
226
227/* Called when the guest wants to close the channel. This is different
228 * from netPipe_closeFromSocket() which is called when the socket is
229 * disconnected. */
230static void
231netPipe_closeFromGuest( void* opaque )
232{
233    NetPipe*  pipe = opaque;
234    netPipe_free(pipe);
235}
236
237
238static int
239netPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
240{
241    NetPipe*  pipe = opaque;
242    int       count = 0;
243    int       ret   = 0;
244    int       buffStart = 0;
245    const GoldfishPipeBuffer* buff = buffers;
246    const GoldfishPipeBuffer* buffEnd = buff + numBuffers;
247
248    for (; buff < buffEnd; buff++)
249        count += buff->size;
250
251    buff = buffers;
252    while (count > 0) {
253        int  avail = buff->size - buffStart;
254        int  len = socket_send(pipe->io->fd, buff->data + buffStart, avail);
255
256        /* the write succeeded */
257        if (len > 0) {
258            buffStart += len;
259            if (buffStart >= buff->size) {
260                buff++;
261                buffStart = 0;
262            }
263            count -= len;
264            ret   += len;
265            continue;
266        }
267
268        /* we reached the end of stream? */
269        if (len == 0) {
270            if (ret == 0)
271                ret = PIPE_ERROR_IO;
272            break;
273        }
274
275        /* if we already wrote some stuff, simply return */
276        if (ret > 0) {
277            break;
278        }
279
280        /* need to return an appropriate error code */
281        if (errno == EAGAIN || errno == EWOULDBLOCK) {
282            ret = PIPE_ERROR_AGAIN;
283        } else {
284            ret = PIPE_ERROR_IO;
285        }
286        break;
287    }
288
289    return ret;
290}
291
292static int
293netPipe_recvBuffers( void* opaque, GoldfishPipeBuffer*  buffers, int  numBuffers )
294{
295    NetPipe*  pipe = opaque;
296    int       count = 0;
297    int       ret   = 0;
298    int       buffStart = 0;
299    GoldfishPipeBuffer* buff = buffers;
300    GoldfishPipeBuffer* buffEnd = buff + numBuffers;
301
302    for (; buff < buffEnd; buff++)
303        count += buff->size;
304
305    buff = buffers;
306    while (count > 0) {
307        int  avail = buff->size - buffStart;
308        int  len = socket_recv(pipe->io->fd, buff->data + buffStart, avail);
309
310        /* the read succeeded */
311        if (len > 0) {
312            buffStart += len;
313            if (buffStart >= buff->size) {
314                buff++;
315                buffStart = 0;
316            }
317            count -= len;
318            ret   += len;
319            continue;
320        }
321
322        /* we reached the end of stream? */
323        if (len == 0) {
324            if (ret == 0)
325                ret = PIPE_ERROR_IO;
326            break;
327        }
328
329        /* if we already read some stuff, simply return */
330        if (ret > 0) {
331            break;
332        }
333
334        /* need to return an appropriate error code */
335        if (errno == EAGAIN || errno == EWOULDBLOCK) {
336            ret = PIPE_ERROR_AGAIN;
337        } else {
338            ret = PIPE_ERROR_IO;
339        }
340        break;
341    }
342    return ret;
343}
344
345static unsigned
346netPipe_poll( void* opaque )
347{
348    NetPipe*  pipe = opaque;
349    unsigned  mask = loopIo_poll(pipe->io);
350    unsigned  ret  = 0;
351
352    if (mask & LOOP_IO_READ)
353        ret |= PIPE_POLL_IN;
354    if (mask & LOOP_IO_WRITE)
355        ret |= PIPE_POLL_OUT;
356
357    return ret;
358}
359
360static void
361netPipe_wakeOn( void* opaque, int flags )
362{
363    NetPipe*  pipe = opaque;
364
365    DD("%s: flags=%d", __FUNCTION__, flags);
366
367    pipe->wakeWanted |= flags;
368    netPipe_resetState(pipe);
369}
370
371
372void*
373netPipe_initTcp( void* hwpipe, void* _looper, const char* args )
374{
375    /* Build SockAddress from arguments. Acceptable formats are:
376     *   <port>
377     */
378    SockAddress  address;
379    uint16_t     port;
380    void*        ret;
381
382    if (args == NULL) {
383        D("%s: Missing address!", __FUNCTION__);
384        return NULL;
385    }
386    D("%s: Port is '%s'", __FUNCTION__, args);
387
388    /* Now, look at the port number */
389    {
390        char* end;
391        long  val = strtol(args, &end, 10);
392        if (end == NULL || *end != '\0' || val <= 0 || val > 65535) {
393            D("%s: Invalid port number: '%s'", __FUNCTION__, args);
394        }
395        port = (uint16_t)val;
396    }
397    sock_address_init_inet(&address, SOCK_ADDRESS_INET_LOOPBACK, port);
398
399    ret = netPipe_initFromAddress(hwpipe, &address, _looper);
400
401    sock_address_done(&address);
402    return ret;
403}
404
405#ifndef _WIN32
406void*
407netPipe_initUnix( void* hwpipe, void* _looper, const char* args )
408{
409    /* Build SockAddress from arguments. Acceptable formats are:
410     *
411     *   <path>
412     */
413    SockAddress  address;
414    void*        ret;
415
416    if (args == NULL || args[0] == '\0') {
417        D("%s: Missing address!", __FUNCTION__);
418        return NULL;
419    }
420    D("%s: Address is '%s'", __FUNCTION__, args);
421
422    sock_address_init_unix(&address, args);
423
424    ret = netPipe_initFromAddress(hwpipe, &address, _looper);
425
426    sock_address_done(&address);
427    return ret;
428}
429#endif
430
431/**********************************************************************
432 **********************************************************************
433 *****
434 *****  N E T W O R K   P I P E   M E S S A G E S
435 *****
436 *****/
437
438static const GoldfishPipeFuncs  netPipeTcp_funcs = {
439    netPipe_initTcp,
440    netPipe_closeFromGuest,
441    netPipe_sendBuffers,
442    netPipe_recvBuffers,
443    netPipe_poll,
444    netPipe_wakeOn,
445    NULL,  /* we can't save these */
446    NULL,  /* we can't load these */
447};
448
449#ifndef _WIN32
450static const GoldfishPipeFuncs  netPipeUnix_funcs = {
451    netPipe_initUnix,
452    netPipe_closeFromGuest,
453    netPipe_sendBuffers,
454    netPipe_recvBuffers,
455    netPipe_poll,
456    netPipe_wakeOn,
457    NULL,  /* we can't save these */
458    NULL,  /* we can't load these */
459};
460#endif
461
462/* This is set to 1 in android_init_opengles() below, and tested
463 * by openglesPipe_init() to refuse a pipe connection if the function
464 * was never called.
465 */
466static int  _opengles_init;
467
468static void*
469openglesPipe_init( void* hwpipe, void* _looper, const char* args )
470{
471    char temp[32];
472    NetPipe *pipe;
473
474    if (!_opengles_init) {
475        /* This should never happen, unless there is a bug in the
476         * emulator's initialization, or the system image. */
477        D("Trying to open the OpenGLES pipe without GPU emulation!");
478        return NULL;
479    }
480
481#ifndef _WIN32
482    if (android_gles_fast_pipes) {
483        char  unix_path[PATH_MAX];
484        android_gles_unix_path(unix_path, sizeof(unix_path), ANDROID_OPENGLES_BASE_PORT);
485        pipe = (NetPipe *)netPipe_initUnix(hwpipe, _looper, unix_path);
486        D("Creating Unix OpenGLES pipe for GPU emulation: %s", unix_path);
487    } else {
488#else /* _WIN32 */
489    {
490#endif
491        /* Connect through TCP as a fallback */
492        snprintf(temp, sizeof temp, "%d", ANDROID_OPENGLES_BASE_PORT);
493        pipe = (NetPipe *)netPipe_initTcp(hwpipe, _looper, temp);
494        D("Creating TCP OpenGLES pipe for GPU emulation!");
495    }
496    if (pipe != NULL) {
497        // Disable TCP nagle algorithm to improve throughput of small packets
498        socket_set_nodelay(pipe->io->fd);
499
500    // On Win32, adjust buffer sizes
501#ifdef _WIN32
502        {
503            int sndbuf = 128 * 1024;
504            int len = sizeof(sndbuf);
505            if (setsockopt(pipe->io->fd, SOL_SOCKET, SO_SNDBUF,
506                        (char*)&sndbuf, len) == SOCKET_ERROR) {
507                D("Failed to set SO_SNDBUF to %d error=0x%x\n",
508                sndbuf, WSAGetLastError());
509            }
510        }
511#endif /* _WIN32 */
512    }
513
514    return pipe;
515}
516
517static const GoldfishPipeFuncs  openglesPipe_funcs = {
518    openglesPipe_init,
519    netPipe_closeFromGuest,
520    netPipe_sendBuffers,
521    netPipe_recvBuffers,
522    netPipe_poll,
523    netPipe_wakeOn,
524    NULL,  /* we can't save these */
525    NULL,  /* we can't load these */
526};
527
528void
529android_net_pipes_init(void)
530{
531    Looper*  looper = looper_newCore();
532
533    goldfish_pipe_add_type( "tcp", looper, &netPipeTcp_funcs );
534#ifndef _WIN32
535    goldfish_pipe_add_type( "unix", looper, &netPipeUnix_funcs );
536#endif
537    goldfish_pipe_add_type( "opengles", looper, &openglesPipe_funcs );
538}
539
540int
541android_init_opengles_pipes(void)
542{
543    /* TODO: Check that we can load and initialize the host emulation
544     *        libraries, and return -1 in case of error.
545     */
546    _opengles_init = 1;
547    return 0;
548}
549