Exemplo n.º 1
0
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;
}