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 "android/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/android/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        status = asyncConnector_init(pipe->connector, address, pipe->io);
208        pipe->state = STATE_CONNECTING;
209
210        if (status == ASYNC_ERROR) {
211            D("%s: Could not connect to socket: %s",
212              __FUNCTION__, errno_str);
213            netPipe_free(pipe);
214            return NULL;
215        }
216        if (status == ASYNC_COMPLETE) {
217            pipe->state = STATE_CONNECTED;
218            netPipe_resetState(pipe);
219        }
220    }
221
222    return pipe;
223}
224
225
226/* Called when the guest wants to close the channel. This is different
227 * from netPipe_closeFromSocket() which is called when the socket is
228 * disconnected. */
229static void
230netPipe_closeFromGuest( void* opaque )
231{
232    NetPipe*  pipe = opaque;
233    netPipe_free(pipe);
234}
235
236static int netPipeReadySend(NetPipe *pipe)
237{
238    if (pipe->state == STATE_CONNECTED)
239        return 0;
240    else if (pipe->state == STATE_CONNECTING)
241        return PIPE_ERROR_AGAIN;
242    else if (pipe->hwpipe == NULL)
243        return PIPE_ERROR_INVAL;
244    else
245        return PIPE_ERROR_IO;
246}
247
248static int
249netPipe_sendBuffers( void* opaque, const GoldfishPipeBuffer* buffers, int numBuffers )
250{
251    NetPipe*  pipe = opaque;
252    int       count = 0;
253    int       ret   = 0;
254    int       buffStart = 0;
255    const GoldfishPipeBuffer* buff = buffers;
256    const GoldfishPipeBuffer* buffEnd = buff + numBuffers;
257
258    ret = netPipeReadySend(pipe);
259    if (ret != 0)
260        return ret;
261
262    for (; buff < buffEnd; buff++)
263        count += buff->size;
264
265    buff = buffers;
266    while (count > 0) {
267        int  avail = buff->size - buffStart;
268        int  len = socket_send(pipe->io->fd, buff->data + buffStart, avail);
269
270        /* the write succeeded */
271        if (len > 0) {
272            buffStart += len;
273            if (buffStart >= buff->size) {
274                buff++;
275                buffStart = 0;
276            }
277            count -= len;
278            ret   += len;
279            continue;
280        }
281
282        /* we reached the end of stream? */
283        if (len == 0) {
284            if (ret == 0)
285                ret = PIPE_ERROR_IO;
286            break;
287        }
288
289        /* if we already wrote some stuff, simply return */
290        if (ret > 0) {
291            break;
292        }
293
294        /* need to return an appropriate error code */
295        if (errno == EAGAIN || errno == EWOULDBLOCK) {
296            ret = PIPE_ERROR_AGAIN;
297        } else {
298            ret = PIPE_ERROR_IO;
299        }
300        break;
301    }
302
303    return ret;
304}
305
306static int
307netPipe_recvBuffers( void* opaque, GoldfishPipeBuffer*  buffers, int  numBuffers )
308{
309    NetPipe*  pipe = opaque;
310    int       count = 0;
311    int       ret   = 0;
312    int       buffStart = 0;
313    GoldfishPipeBuffer* buff = buffers;
314    GoldfishPipeBuffer* buffEnd = buff + numBuffers;
315
316    for (; buff < buffEnd; buff++)
317        count += buff->size;
318
319    buff = buffers;
320    while (count > 0) {
321        int  avail = buff->size - buffStart;
322        int  len = socket_recv(pipe->io->fd, buff->data + buffStart, avail);
323
324        /* the read succeeded */
325        if (len > 0) {
326            buffStart += len;
327            if (buffStart >= buff->size) {
328                buff++;
329                buffStart = 0;
330            }
331            count -= len;
332            ret   += len;
333            continue;
334        }
335
336        /* we reached the end of stream? */
337        if (len == 0) {
338            if (ret == 0)
339                ret = PIPE_ERROR_IO;
340            break;
341        }
342
343        /* if we already read some stuff, simply return */
344        if (ret > 0) {
345            break;
346        }
347
348        /* need to return an appropriate error code */
349        if (errno == EAGAIN || errno == EWOULDBLOCK) {
350            ret = PIPE_ERROR_AGAIN;
351        } else {
352            ret = PIPE_ERROR_IO;
353        }
354        break;
355    }
356    return ret;
357}
358
359static unsigned
360netPipe_poll( void* opaque )
361{
362    NetPipe*  pipe = opaque;
363    unsigned  mask = loopIo_poll(pipe->io);
364    unsigned  ret  = 0;
365
366    if (mask & LOOP_IO_READ)
367        ret |= PIPE_POLL_IN;
368    if (mask & LOOP_IO_WRITE)
369        ret |= PIPE_POLL_OUT;
370
371    return ret;
372}
373
374static void
375netPipe_wakeOn( void* opaque, int flags )
376{
377    NetPipe*  pipe = opaque;
378
379    DD("%s: flags=%d", __FUNCTION__, flags);
380
381    pipe->wakeWanted |= flags;
382    netPipe_resetState(pipe);
383}
384
385
386void*
387netPipe_initTcp( void* hwpipe, void* _looper, const char* args )
388{
389    /* Build SockAddress from arguments. Acceptable formats are:
390     *   <port>
391     */
392    SockAddress  address;
393    uint16_t     port;
394    void*        ret;
395
396    if (args == NULL) {
397        D("%s: Missing address!", __FUNCTION__);
398        return NULL;
399    }
400    D("%s: Port is '%s'", __FUNCTION__, args);
401
402    /* Now, look at the port number */
403    {
404        char* end;
405        long  val = strtol(args, &end, 10);
406        if (end == NULL || *end != '\0' || val <= 0 || val > 65535) {
407            D("%s: Invalid port number: '%s'", __FUNCTION__, args);
408        }
409        port = (uint16_t)val;
410    }
411    sock_address_init_inet(&address, SOCK_ADDRESS_INET_LOOPBACK, port);
412
413    ret = netPipe_initFromAddress(hwpipe, &address, _looper);
414
415    sock_address_done(&address);
416    return ret;
417}
418
419#ifndef _WIN32
420void*
421netPipe_initUnix( void* hwpipe, void* _looper, const char* args )
422{
423    /* Build SockAddress from arguments. Acceptable formats are:
424     *
425     *   <path>
426     */
427    SockAddress  address;
428    void*        ret;
429
430    if (args == NULL || args[0] == '\0') {
431        D("%s: Missing address!", __FUNCTION__);
432        return NULL;
433    }
434    D("%s: Address is '%s'", __FUNCTION__, args);
435
436    sock_address_init_unix(&address, args);
437
438    ret = netPipe_initFromAddress(hwpipe, &address, _looper);
439
440    sock_address_done(&address);
441    return ret;
442}
443#endif
444
445/**********************************************************************
446 **********************************************************************
447 *****
448 *****  N E T W O R K   P I P E   M E S S A G E S
449 *****
450 *****/
451
452static const GoldfishPipeFuncs  netPipeTcp_funcs = {
453    netPipe_initTcp,
454    netPipe_closeFromGuest,
455    netPipe_sendBuffers,
456    netPipe_recvBuffers,
457    netPipe_poll,
458    netPipe_wakeOn,
459    NULL,  /* we can't save these */
460    NULL,  /* we can't load these */
461};
462
463#ifndef _WIN32
464static const GoldfishPipeFuncs  netPipeUnix_funcs = {
465    netPipe_initUnix,
466    netPipe_closeFromGuest,
467    netPipe_sendBuffers,
468    netPipe_recvBuffers,
469    netPipe_poll,
470    netPipe_wakeOn,
471    NULL,  /* we can't save these */
472    NULL,  /* we can't load these */
473};
474#endif
475
476/* This is set to 1 in android_init_opengles() below, and tested
477 * by openglesPipe_init() to refuse a pipe connection if the function
478 * was never called.
479 */
480static int  _opengles_init;
481
482static void*
483openglesPipe_init( void* hwpipe, void* _looper, const char* args )
484{
485    NetPipe *pipe;
486
487    if (!_opengles_init) {
488        /* This should never happen, unless there is a bug in the
489         * emulator's initialization, or the system image. */
490        D("Trying to open the OpenGLES pipe without GPU emulation!");
491        return NULL;
492    }
493
494    char server_addr[PATH_MAX];
495    android_gles_server_path(server_addr, sizeof(server_addr));
496#ifndef _WIN32
497    if (android_gles_fast_pipes) {
498        pipe = (NetPipe *)netPipe_initUnix(hwpipe, _looper, server_addr);
499        D("Creating Unix OpenGLES pipe for GPU emulation: %s", server_addr);
500    } else {
501#else /* _WIN32 */
502    {
503#endif
504        /* Connect through TCP as a fallback */
505        pipe = (NetPipe *)netPipe_initTcp(hwpipe, _looper, server_addr);
506        D("Creating TCP OpenGLES pipe for GPU emulation!");
507    }
508    if (pipe != NULL) {
509        // Disable TCP nagle algorithm to improve throughput of small packets
510        socket_set_nodelay(pipe->io->fd);
511
512    // On Win32, adjust buffer sizes
513#ifdef _WIN32
514        {
515            int sndbuf = 128 * 1024;
516            int len = sizeof(sndbuf);
517            if (setsockopt(pipe->io->fd, SOL_SOCKET, SO_SNDBUF,
518                        (char*)&sndbuf, len) == SOCKET_ERROR) {
519                D("Failed to set SO_SNDBUF to %d error=0x%x\n",
520                sndbuf, WSAGetLastError());
521            }
522        }
523#endif /* _WIN32 */
524    }
525
526    return pipe;
527}
528
529static const GoldfishPipeFuncs  openglesPipe_funcs = {
530    openglesPipe_init,
531    netPipe_closeFromGuest,
532    netPipe_sendBuffers,
533    netPipe_recvBuffers,
534    netPipe_poll,
535    netPipe_wakeOn,
536    NULL,  /* we can't save these */
537    NULL,  /* we can't load these */
538};
539
540void
541android_net_pipes_init(void)
542{
543    Looper*  looper = looper_newCore();
544
545    goldfish_pipe_add_type( "tcp", looper, &netPipeTcp_funcs );
546#ifndef _WIN32
547    goldfish_pipe_add_type( "unix", looper, &netPipeUnix_funcs );
548#endif
549    goldfish_pipe_add_type( "opengles", looper, &openglesPipe_funcs );
550}
551
552int
553android_init_opengles_pipes(void)
554{
555    /* TODO: Check that we can load and initialize the host emulation
556     *        libraries, and return -1 in case of error.
557     */
558    _opengles_init = 1;
559    return 0;
560}
561