gboolean RpcChannel_Destroy(RpcChannel *chan) { size_t i; RpcChannelInt *cdata = (RpcChannelInt *) chan; if (cdata->impl.funcs != NULL && cdata->impl.funcs->shutdown != NULL) { cdata->impl.funcs->shutdown(chan); } RpcChannel_UnregisterCallback(chan, &cdata->resetReg); for (i = 0; i < ARRAYSIZE(gRpcHandlers); i++) { RpcChannel_UnregisterCallback(chan, &gRpcHandlers[i]); } if (cdata->rpcs != NULL) { g_hash_table_destroy(cdata->rpcs); cdata->rpcs = NULL; } cdata->resetCb = NULL; cdata->resetData = NULL; cdata->appCtx = NULL; g_free(cdata->appName); cdata->appName = NULL; if (cdata->mainCtx != NULL) { g_main_context_unref(cdata->mainCtx); cdata->mainCtx = NULL; } if (cdata->resetCheck != NULL) { g_source_destroy(cdata->resetCheck); cdata->resetCheck = NULL; } g_free(cdata); return TRUE; }
DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(RpcChannel *chan) : mRpcChannel(chan) #else DnDCPTransportGuestRpc::DnDCPTransportGuestRpc(void) #endif { for (int i = 0; i < TRANSPORT_INTERFACE_MAX; i++) { mCBCtx[i].transport = this; mCBCtx[i].type = (TransportInterfaceType)i; } } /** * Register a rpc callback to an interface. * * @param[in] rpc rpc which is listening to the message. * @param[in] type the interface type rpc is listening to. * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::RegisterRpc(RpcBase *rpc, TransportInterfaceType type) { if (mTables.GetRpc(type)) { LOG(0, ("%s: the type %d is already registered\n", __FUNCTION__, type)); UnregisterRpc(type); } const char *cmdStr = (const char *)mTables.GetCmdStr(type); const char *disableStr = mTables.GetDisableStr(type); if (!cmdStr || !disableStr) { LOG(0, ("%s: can not find valid cmd for %d, cmdStr %s disableStr %s\n", __FUNCTION__, type, (cmdStr ? cmdStr : "NULL"), (disableStr ? disableStr : "NULL"))); return false; } ASSERT(mCBCtx); ASSERT(type == TRANSPORT_GUEST_CONTROLLER_DND || type == TRANSPORT_GUEST_CONTROLLER_CP || type == TRANSPORT_GUEST_CONTROLLER_FT); LOG(4, ("%s: for %s\n", __FUNCTION__, cmdStr)); #ifdef VMX86_TOOLS ASSERT(mRpcChannel); mRpcChanCBList[type].name = cmdStr; mRpcChanCBList[type].callback = RecvMsgCB; mRpcChanCBList[type].clientData = &mCBCtx[type]; mRpcChanCBList[type].xdrIn = NULL; mRpcChanCBList[type].xdrOut = NULL; mRpcChanCBList[type].xdrInSize = 0; RpcChannel_RegisterCallback(mRpcChannel, &mRpcChanCBList[type]); #else GuestRpc_RegisterCommand(mTables.GetCmd(type), disableStr, (const unsigned char *)cmdStr, RecvMsgCB, &mCBCtx[type]); #endif mTables.SetRpc(type, rpc); return true; } /** * Unregister a rpc callback. * * @param[in] type the interface type rpc is listening to. * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::UnregisterRpc(TransportInterfaceType type) { if (!mTables.GetRpc(type)) { LOG(0, ("%s: the type %d is not registered\n", __FUNCTION__, type)); return false; } #ifdef VMX86_TOOLS ASSERT(mRpcChannel); RpcChannel_UnregisterCallback(mRpcChannel, &mRpcChanCBList[type]); #else GuestRpc_UnregisterCommand(mTables.GetCmd(type)); #endif mTables.SetRpc(type, NULL); return true; } /** * Wrap the buffer into an rpc and send it to the peer. * * @param[ignored] destId destination address id * @param[in] type transport interface type * @param[in] data Payload buffer * @param[in] dataSize Payload buffer size * * @return true on success, false otherwise. */ bool DnDCPTransportGuestRpc::SendPacket(uint32 destId, TransportInterfaceType type, const uint8 *msg, size_t length) { char *rpc = NULL; size_t rpcSize = 0; size_t nrWritten = 0; const char *cmd = mTables.GetCmdStr(type); bool ret = true; if (!cmd) { LOG(0, ("%s: can not find valid cmd for %d\n", __FUNCTION__, type)); return false; } rpcSize = strlen(cmd) + 1 + length; rpc = (char *)Util_SafeMalloc(rpcSize); nrWritten = Str_Sprintf(rpc, rpcSize, "%s ", cmd); if (length > 0) { ASSERT(nrWritten + length <= rpcSize); memcpy(rpc + nrWritten, msg, length); } #ifdef VMX86_TOOLS ret = (TRUE == RpcChannel_Send(mRpcChannel, rpc, rpcSize, NULL, NULL)); if (!ret) { LOG(0, ("%s: failed to send msg to host\n", __FUNCTION__)); } free(rpc); #else GuestRpc_SendWithTimeOut((const unsigned char *)TOOLS_DND_NAME, (const unsigned char *)rpc, rpcSize, GuestRpc_GenericCompletionRoutine, rpc, DND_TIMEOUT); #endif return ret; }