blob: 28f22b1e49c2f58b35e7198e59443293d90e19a6 [file] [log] [blame]
/* Copyright 2015 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.
*/
#pragma once
#include "android/emulation/android_pipe_common.h"
#include "android/utils/compiler.h"
#include "android/utils/stream.h"
#include <stdbool.h>
#include <stdint.h>
ANDROID_BEGIN_HEADER
// TECHNICAL NOTE:
//
// An Android pipe is a very fast communication channel between the guest
// system and the emulator program.
//
// To open a new pipe to the emulator, a guest client will do the following:
//
// fd = open("/dev/qemu_pipe", O_RDWR);
// ret = write(fd, pipeServiceName, strlen(pipeServiceName) + 1);
// if (ret < 0) {
// // something bad happened, see errno
// }
//
// Where 'pipeServiceName' is a string that looke like "pipe:<service>"
// or "pipe:<service>:<args>", terminated by a zero.
//
// now read()/write() to communicate with <pipeServiceName> service in the
// emulator. select() and non-blocking i/o will also work properly.
//
// The Goldfish pipe virtual device is in charge of communicating with the
// kernel to manage pipe operations.
//
// Each pipe connection corresponds to two objects:
//
// - A hardware-side opaque object (implemented by the virtual pipe device)
// identified here as a |hwpipe| value.
//
// - A host-specific opaque object, identified here either as |host-pipe|.
//
// (virtual device) |hwpipe| <-----> |host-pipe| (emulator)
//
// Expected usage is the following:
//
// 1/ During setup, the virtual device should call android_pipe_set_hw_funcs()
// to point to callbacks it provides to implement a few functions called
// from the host, later at runtime.
//
// 2/ During setup, the emulator should register host pipe service instances,
// each one identified by a name, before the VM starts.
//
// 3/ At runtime, when a guest opens /dev/goldfish_pipe, this ends up creating
// a new |hwpipe| object in the virtual device, which will then call
// android_pipe_guest_open() to create a corresponding |host-pipe|
// object.
//
// Note that at this point, the |host-pipe| corresponds to a special
// host-side pipe state that waits for the name of the pipe service to
// connect to, and potential arguments. This is called a |connect-pipe|
// here:
//
// android_pipe_guest_open()
// |hwpipe| <---------------------------> |connect-pipe|
//
// 4/ When the pipe service name is fully written, the |connect-pipe| finds a
// service registered for it, and calls its ::init() callback to create
// a new |service-pipe| instance.
//
// |hwpipe| <---------------------------> |connect-pipe|
//
// |service-pipe|
//
// 5/ It then calls the AndroidPipeHwFuncs::resetPipe() callback provided
// by the virtual device to reattach the |hwpipe| to the |service-pipe|
// then later delete the now-useless |connect-pipe|.
//
// |hwpipe| <------------+ |connect-pipe|
// |
// +---------------->|service-pipe|
//
// VERY IMPORTANT NOTE:
//
// All operations should happen on the thread that currently holds the
// global VM state lock (see android/emulation/VmLock.h). It's up to
// the host implementation to ensure that this is always the case.
//
////////////////////////////////////////////////////////////////////////////
//
// The following functions are called from the virtual device only and are
// implemented by AndroidEmu. They will always be called from the device thread
// context as well.
// Open a new Android pipe. |hwpipe| is a unique pointer value identifying the
// hardware-side view of the pipe, and will be passed to the 'init' callback
// from AndroidPipeHwFuncs. This returns a new |internal-pipe| value that is
// only used by the virtual device to call android_pipe_xxx() functions below.
extern void* android_pipe_guest_open(void* hwpipe);
// Close and free an Android pipe. |pipe| must be the result of a previous
// android_pipe_guest_open() call or the second parameter to
// android_pipe_reset().
// This must *not* be called from the host side, see android_pipe_host_close()
// instead.
extern void android_pipe_guest_close(void* internal_pipe);
// Save the state of an Android pipe to a stream. |internal_pipe| is the pipe
// instance from android_pipe_guest_open() or android_pipe_guest_load(), and
// |file| is the
// output stream.
extern void android_pipe_guest_save(void* internal_pipe, Stream* file);
// Load the state of an Android pipe from a stream. |file| is the input stream,
// |hwpipe| is the hardware-side pipe descriptor. On success, return a new
// internal pipe instance (similar to one returned by
// android_pipe_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.
extern void* android_pipe_guest_load(Stream* file,
void* hwpipe,
char* force_close);
// Similar to android_pipe_guest_load(), but this function is only called from
// the
// QEMU1 virtual pipe device, to support legacy snapshot formats. It can be
// ignored by the QEMU2 virtual device implementation.
//
// The difference is that this must also read the hardware-specific state
// fields, and store them into |*channel|, |*wakes| and |*closed| on
// success.
extern void* android_pipe_guest_load_legacy(Stream* file,
void* hwpipe,
uint64_t* channel,
unsigned char* wakes,
unsigned char* closed,
char* force_close);
// Call the poll() callback of the client associated with |pipe|.
extern unsigned android_pipe_guest_poll(void* internal_pipe);
// Call the recvBuffers() callback of the client associated with |pipe|.
extern int android_pipe_guest_recv(void* internal_pipe,
AndroidPipeBuffer* buffers,
int numBuffers);
// Call the sendBuffers() callback of the client associated with |pipe|.
extern int android_pipe_guest_send(void* internal_pipe,
const AndroidPipeBuffer* buffer,
int numBuffer);
// Call the wakeOn() callback of the client associated with |pipe|.
extern void android_pipe_guest_wake_on(void* internal_pipe, unsigned wakes);
// A set of functions that must be implemented by the virtual device
// implementation. Used with call android_pipe_set_hw_funcs().
typedef struct AndroidPipeHwFuncs {
// Change the internal pipe associated with |hwpipe| to be |internal_pipe|
void (*resetPipe)(void* hwpipe, void* internal_pipe);
void (*closeFromHost)(void* hwpipe);
void (*signalWake)(void* hwpipe, unsigned flags);
} AndroidPipeHwFuncs;
// Change the set of AndroidPipeHwFuncs corresponding to the hardware virtual
// device, return the old value. This must be called from the virtual device
// when it is realized / initialized.
extern const AndroidPipeHwFuncs* android_pipe_set_hw_funcs(
const AndroidPipeHwFuncs* hw_funcs);
ANDROID_END_HEADER