| /* Copyright (C) 2016 The Android Open Source Project |
| ** |
| ** This software is licensed under the terms of the GNU General Public |
| ** License version 2, as published by the Free Software Foundation, and |
| ** may be copied, distributed, and modified under those terms. |
| ** |
| ** This program is distributed in the hope that it will be useful, |
| ** but WITHOUT ANY WARRANTY; without even the implied warranty of |
| ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| ** GNU General Public License for more details. |
| */ |
| #ifndef _HW_GOLDFISH_PIPE_H |
| #define _HW_GOLDFISH_PIPE_H |
| |
| #include "qemu/typedefs.h" |
| |
| #include <stdbool.h> |
| #include <stddef.h> |
| #include <stdint.h> |
| |
| /* The Android pipe virtual device expects an implementation of |
| * pipe services to be provided according to the following interface |
| */ |
| typedef struct GoldfishPipeBuffer { |
| void* data; |
| size_t size; |
| } GoldfishPipeBuffer; |
| |
| /* List of bitflags returned by guest_poll() */ |
| typedef enum { |
| GOLDFISH_PIPE_POLL_IN = (1 << 0), /* means guest can read */ |
| GOLDFISH_PIPE_POLL_OUT = (1 << 1), /* means guest can write */ |
| GOLDFISH_PIPE_POLL_HUP = (1 << 2), /* means closed by host */ |
| } GoldfishPipePollFlags; |
| |
| /* List of bitflags used to call goldfish_pipe_signal_wake() and |
| * guest_wake_on() */ |
| typedef enum { |
| GOLDFISH_PIPE_WAKE_CLOSED = (1 << 0), /* emulator closed the pipe */ |
| GOLDFISH_PIPE_WAKE_READ = (1 << 1), /* pipe can now be read from */ |
| GOLDFISH_PIPE_WAKE_WRITE = (1 << 2), /* pipe can now be written to */ |
| } GoldfishPipeWakeFlags; |
| |
| /* List of error values possibly returned by guest_recv() and |
| * guest_send(). */ |
| typedef enum { |
| GOLDFISH_PIPE_ERROR_INVAL = -1, |
| GOLDFISH_PIPE_ERROR_AGAIN = -2, |
| GOLDFISH_PIPE_ERROR_NOMEM = -3, |
| GOLDFISH_PIPE_ERROR_IO = -4, |
| } GoldfishPipeError; |
| |
| /* Opaque type of the hardware-side view of a pipe connection. This structure |
| * is implemented by the virtual device and is hidden from the host service |
| * implementation. */ |
| typedef struct GoldfishHwPipe GoldfishHwPipe; |
| |
| /* Opaque type of the host-side view of a pipe connection. This structure is |
| * implemented by the host pipe service implementation, and is hidden from |
| * the virtual device. */ |
| typedef struct GoldfishHostPipe GoldfishHostPipe; |
| |
| typedef struct { |
| // Open a new pipe. |hw_pipe| is a unique pointer value identifying the |
| // hardware-side view of the pipe, and will be passed to the |
| // goldfish_pipe_xxx() functions below. This returns a new host-specific |
| // pipe value that is only used by the virtual device to call other |
| // callbacks here. There is a one-to-one association between a |hw_pipe| |
| // and its |host_pipe| value, which can be reset by calling |
| // goldfish_pipe_reset(). |
| GoldfishHostPipe* (*guest_open)(GoldfishHwPipe *hw_pipe); |
| |
| // Load the state of a pipe from a stream. |file| is the input stream, |
| // |hw_pipe| is the hardware-side pipe descriptor. On success, return a new |
| // internal pipe instance (similar to one returned by guest_open()), and |
| // sets |*force_close| to 1 to indicate that the pipe must be force-closed |
| // just after its load/creation (only useful for certain services that can't |
| // preserve state into streams). Return NULL on faillure. |
| GoldfishHostPipe* (*guest_load)(QEMUFile *file, GoldfishHwPipe *hw_pipe, |
| char *force_close); |
| |
| // Close and free a pipe. |host_pipe| must be the result of a previous |
| // guest_open() or guest_load() call, or the second parameter to |
| // goldfish_pipe_reset(). |
| void (*guest_close)(GoldfishHostPipe *host_pipe); |
| |
| // Save the state of a pipe to a stream. |host_pipe| is the pipe |
| // instance from guest_open() or guest_load(). and |file| is the |
| // output stream. |
| void (*guest_save)(GoldfishHostPipe *host_pipe, QEMUFile *file); |
| |
| // Poll the state of the pipe associated with |host_pipe|. |
| // This returns a combination of GoldfishPipePollFlags. |
| GoldfishPipePollFlags (*guest_poll)(GoldfishHostPipe *host_pipe); |
| |
| // Called when the guest tries to receive data from the host through |
| // |host_pipe|. This will try to copy data to the memory ranges |
| // decribed by the array |buffers| or |num_buffers| items. |
| // Return number of bytes transferred, or a (negative) GoldfishPipeError |
| // value otherwise. |
| int (*guest_recv)(GoldfishHostPipe *host_pipe, |
| GoldfishPipeBuffer *buffers, |
| int num_buffers); |
| |
| // Called when the guest tries to send data to the host through |
| // |host_pipe|. This will try to copy data from the memory ranges |
| // decribed by the array |buffers| or |num_buffers| items. |
| // Return number of bytes transferred, or a (negative) GoldfishPipeError |
| // value otherwise. |
| int (*guest_send)(GoldfishHostPipe *host_pipe, |
| const GoldfishPipeBuffer *buffers, |
| int num_buffers); |
| |
| // Called when the guest wants to be waked on specific events. |
| // identified by the |wake_flags| bitmask. The host should call |
| // goldfish_pipe_signal_wake() with the appropriate bitmask when |
| // any of these events occur. |
| void (*guest_wake_on)(GoldfishHostPipe *host_pipe, |
| GoldfishPipeWakeFlags wake_flags); |
| } GoldfishPipeServiceOps; |
| |
| /* Called by the service implementation to register its callbacks. |
| * The default implementation doesn't do anything except returning |
| * an error when |guest_open| or |guest_load| are called. */ |
| extern void goldfish_pipe_set_service_ops( |
| const GoldfishPipeServiceOps* ops); |
| |
| /* Implemented by the virtual device, always called from the service in |
| * a thread that owns the BQL. */ |
| |
| /* Reset the association of |hw_pipe| with a new |host_pipe| |
| * value. This is called once the guest has written the service name |
| * to the initial pipe connection, and the host decided of the right |
| * implementation for it. */ |
| extern void goldfish_pipe_reset(GoldfishHwPipe *hw_pipe, |
| GoldfishHostPipe *host_pipe); |
| |
| /* Called by the host to notify the virtual device that it has |
| * closed its side of the pipe. */ |
| extern void goldfish_pipe_close_from_host(GoldfishHwPipe *hw_pipe); |
| |
| /* Called by the host to notify that one or more conditions identified |
| * by |flags| has been met for a given pipe identified by |hw_pipe|. */ |
| extern void goldfish_pipe_signal_wake(GoldfishHwPipe *hw_pipe, |
| GoldfishPipeWakeFlags flags); |
| |
| #endif /* _HW_GOLDFISH_PIPE_H */ |