1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175
|
/*********************************************************
* Copyright (C) 2008 VMware, Inc. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation version 2.1 and no later version.
*
* 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 Lesser GNU General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
*********************************************************/
#ifndef _RPCCHANNEL_H_
#define _RPCCHANNEL_H_
/**
* @file rpcChannel.h
*
* Defines the interface between applications and the underlying GuestRPC
* channel. The goal is to have an abstraction so applications can run over
* the backdoor, VMCI sockets or TCP/IP sockets by just picking up the
* desired channel at runtime, without the need to modify the code.
*
* For this reason, the behavior of all channels is modeled after the RpcIn
* channel currently used in Tools, so the socket-based channels won't
* provide much better functionality than what the backdoor provides (aside
* from being interrupt-based rather than poll-based).
*
* @addtogroup vmtools_guestrpc
* @{
*/
#if !defined(VMTOOLS_USE_GLIB)
# error "This library needs to be compiled with VMTOOLS_USE_GLIB."
#endif
#include <rpc/rpc.h>
#include "vm_basic_types.h"
#include "rpcin.h"
struct RpcChannel;
/** Defines the registration data for a GuestRPC application. */
typedef struct RpcChannelCallback {
/** String identifying the RPC message. */
const char *name;
/** Function to call when data arrives. */
RpcIn_Callback callback;
/** Data to provide to callback function. */
gpointer clientData;
/** If not NULL, the input data will be deserialized using this function. */
gpointer xdrIn;
/**
* If not NULL, the output data will be serialized using this function. The
* output data should be stored in the @a result field of the RpcInData
* structure, and should have been allocated with glib's @a g_malloc() if
* @a freeResult is TRUE.
*/
gpointer xdrOut;
/**
* If xdrIn is not NULL, this should be the amount of memory to allocate
* for deserializing the input data.
*/
size_t xdrInSize;
} RpcChannelCallback;
typedef Bool (*RpcChannelStartFn)(struct RpcChannel *);
typedef void (*RpcChannelStopFn)(struct RpcChannel *);
typedef void (*RpcChannelShutdownFn)(struct RpcChannel *);
typedef Bool (*RpcChannelSendFn)(struct RpcChannel *,
char *data,
size_t dataLen,
char **result,
size_t *resultLen);
/**
* Signature for the callback function called after a channel reset.
*
* @param[in] chan The RPC channel.
* @param[in] success Whether reset was successful.
* @param[in] data Client data.
*/
typedef void (*RpcChannelResetCb)(struct RpcChannel *chan,
gboolean success,
gpointer data);
/** Defines the interface between the application and the RPC channel. */
typedef struct RpcChannel {
RpcChannelStartFn start;
RpcChannelStopFn stop;
RpcChannelSendFn send;
/* Private section: don't use the fields below directly. */
RpcChannelShutdownFn shutdown;
gchar *appName;
GHashTable *rpcs;
GMainContext *mainCtx;
GSource *resetCheck;
gpointer appCtx;
RpcChannelCallback resetReg;
RpcChannelResetCb resetCb;
gpointer resetData;
gboolean rpcError;
guint rpcErrorCount;
gpointer _private;
} RpcChannel;
/**
* Wrapper for the send function of an RPC channel struct.
*
* @param[in] chan The RPC channel instance.
* @param[in] data Data to send.
* @param[in] dataLen Number of bytes to send.
* @param[out] result Response from other side.
* @param[out] resultLen Number of bytes in response.
*
* @return The status from the remote end (TRUE if call was successful).
*/
static INLINE Bool
RpcChannel_Send(RpcChannel *chan,
char *data,
size_t dataLen,
char **result,
size_t *resultLen)
{
return chan->send(chan, data, dataLen, result, resultLen);
}
Bool
RpcChannel_BuildXdrCommand(const char *cmd,
void *xdrProc,
void *xdrData,
char **result,
size_t *resultLen);
gboolean
RpcChannel_Destroy(RpcChannel *chan);
Bool
RpcChannel_Dispatch(RpcInData *data);
void
RpcChannel_Setup(RpcChannel *chan,
const gchar *appName,
GMainContext *mainCtx,
gpointer appCtx,
RpcChannelResetCb resetCb,
gpointer resetData);
void
RpcChannel_RegisterCallback(RpcChannel *chan,
RpcChannelCallback *rpc);
void
RpcChannel_UnregisterCallback(RpcChannel *chan,
RpcChannelCallback *rpc);
RpcChannel *
RpcChannel_NewBackdoorChannel(GMainContext *mainCtx);
/** @} */
#endif
|