예제 #1
0
void LMEConnection::_doRX()
{
	unsigned int bytesRead;
	int status = 1;

	_threadStartedEvent.set();

	unsigned char *rxBuffer = new unsigned char[_heci.GetBufferSize()];

	while (true) {
		bytesRead = (unsigned int)_receiveMessage(rxBuffer, _heci.GetBufferSize());

		if ((int)bytesRead < 0) {
			PRINT("Error receiving data from HECI\n");
			Deinit();
			break;
		}

		if (bytesRead == 0) {
			// ERROR
			continue;
		}

		PRINT("Received from LME %d bytes (msg type %02d)\n", bytesRead, rxBuffer[0]);

		if (!_checkMinMsgSize(rxBuffer, bytesRead)) {
			PRINT("Error receiving data from HECI\n");
			Deinit();
			break;
		}

		if (plugin.preprocess(rxBuffer, bytesRead) == LMS_DROPPED) {
			continue;
		}

		switch (rxBuffer[0]) {
		case APF_DISCONNECT:
			{
				LMEDisconnectMessage disconnectMessage(
				    (APF_DISCONNECT_REASON_CODE)ntohl(
					((APF_DISCONNECT_MESSAGE *)rxBuffer)->ReasonCode));

				_cb(_cbParam, &disconnectMessage, sizeof(disconnectMessage), &status);
			}
			break;

		case APF_SERVICE_REQUEST:
			{
				APF_SERVICE_REQUEST_MESSAGE *pMessage =
					(APF_SERVICE_REQUEST_MESSAGE *)rxBuffer;
				LMEServiceRequestMessage serviceRequestMessage;

				serviceRequestMessage.ServiceName.append(
					(char *)(pMessage->ServiceName),
					ntohl(pMessage->ServiceNameLength));

				_cb(_cbParam, &serviceRequestMessage, sizeof(serviceRequestMessage), &status);
			}
			break;

		case APF_USERAUTH_REQUEST:
			_apfUserAuthRequest(rxBuffer, bytesRead, &status);
			break;

		case APF_GLOBAL_REQUEST:
			_apfGlobalRequest(rxBuffer, bytesRead, &status);
			break;

		case APF_CHANNEL_OPEN:
			_apfChannelOpen(rxBuffer, bytesRead, &status);
			break;

		case APF_CHANNEL_OPEN_CONFIRMATION:
			{
				APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *pMessage =
				    (APF_CHANNEL_OPEN_CONFIRMATION_MESSAGE *)rxBuffer;
				LMEChannelOpenReplaySuccessMessage channelOpenReply;

				channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel);
				channelOpenReply.SenderChannel = ntohl(pMessage->SenderChannel);
				channelOpenReply.InitialWindow = ntohl(pMessage->InitialWindowSize);
				_cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status);
			}
			break;

		case APF_CHANNEL_OPEN_FAILURE:
			{
				APF_CHANNEL_OPEN_FAILURE_MESSAGE *pMessage =
				    (APF_CHANNEL_OPEN_FAILURE_MESSAGE *)rxBuffer;
				LMEChannelOpenReplayFailureMessage channelOpenReply;

				channelOpenReply.RecipientChannel = ntohl(pMessage->RecipientChannel);
				channelOpenReply.ReasonCode =
					(OPEN_FAILURE_REASON)(ntohl(pMessage->ReasonCode));
				_cb(_cbParam, &channelOpenReply, sizeof(channelOpenReply), &status);
			}
			break;

		case APF_CHANNEL_CLOSE:
			{
				APF_CHANNEL_CLOSE_MESSAGE *pMessage =
				    (APF_CHANNEL_CLOSE_MESSAGE *)rxBuffer;
				LMEChannelCloseMessage channelClose;

				channelClose.RecipientChannel = ntohl(pMessage->RecipientChannel);
				_cb(_cbParam, &channelClose, sizeof(channelClose), &status);
			}
			break;

		case APF_CHANNEL_DATA:
			{
				APF_CHANNEL_DATA_MESSAGE *pMessage =
				    (APF_CHANNEL_DATA_MESSAGE *)rxBuffer;
				LMEChannelDataMessage channelData(ntohl(pMessage->RecipientChannel),
								  ntohl(pMessage->DataLength),
								  pMessage->Data);
				_cb(_cbParam, &channelData, sizeof(channelData), &status);
			}
			break;

		case APF_CHANNEL_WINDOW_ADJUST:
			{
				APF_WINDOW_ADJUST_MESSAGE *pMessage =
				    (APF_WINDOW_ADJUST_MESSAGE *)rxBuffer;
				LMEChannelWindowAdjustMessage channelWindowAdjust;

				channelWindowAdjust.RecipientChannel = ntohl(pMessage->RecipientChannel);
				channelWindowAdjust.BytesToAdd = ntohl(pMessage->BytesToAdd);
				_cb(_cbParam, &channelWindowAdjust, sizeof(channelWindowAdjust), &status);
			}
			break;

		case APF_PROTOCOLVERSION:
			{
				APF_PROTOCOL_VERSION_MESSAGE *pMessage =
				    (APF_PROTOCOL_VERSION_MESSAGE *)rxBuffer;
				LMEProtocolVersionMessage protVersion;

				protVersion.MajorVersion = ntohl(pMessage->MajorVersion);
				protVersion.MinorVersion = ntohl(pMessage->MinorVersion);
				protVersion.TriggerReason =
					(APF_TRIGGER_REASON)ntohl(pMessage->TriggerReason);
				_cb(_cbParam, &protVersion, sizeof(protVersion), &status);
			}
			break;

		default:
			// Uknown request. Ignore
			break;
		}

		if (IsInitialized()) {
			plugin.postprocess(rxBuffer, bytesRead, status);
		}
	}

	if (rxBuffer != NULL) {
		delete[] rxBuffer;
	}
}
void RemoteViewerCore::execute()
{
  try {
    // connect to host and create RfbInputGate/RfbOutputGate
    // if already connected, then function do nothing
    m_logWriter.info(_T("Protocol stage is \"Connection establishing\"."));
    if (!connectToHost())
      return;

    // get server version and set client version
    m_logWriter.info(_T("Protocol stage is \"Handshake\"."));
    handshake();

    // negotiaty about security type and authenticate
    m_logWriter.info(_T("Protocol stage is \"Authentication\"."));
    authenticate();

    // set shared flag, get server dimension, pixel format and hostname
    // send client pixel format and set him.
    m_logWriter.info(_T("Protocol stage is \"Initialization\"."));
    clientAndServerInit();

    // is connected
    m_logWriter.info(_T("Protocol stage is \"Is connected\"."));

    try {
      m_adapter->onConnected(m_output);
    } catch (const Exception &ex) {
      m_logWriter.error(_T("Error in CoreEventsAdapter::onConnected(): %s"), ex.getMessage());
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onConnected()"));
    }

    {
      AutoLock al(&m_connectLock);
      m_wasConnected = true;
    }

    // send supporting encoding
    m_logWriter.info(_T("Protocol stage is \"Encoding select\"."));
    sendEncodings();

    // send request of frame buffer update
    m_logWriter.info(_T("Protocol stage is \"Working phase\"."));
    sendFbUpdateRequest(false);

    // received server messages
    while (!isTerminating()) {
      UINT32 msgType = receiveServerMessageType();

      switch (msgType) {
      case ServerMsgDefs::FB_UPDATE:
        m_logWriter.detail(_T("Received message: FB_UPDATE"));
        receiveFbUpdate();
        break;

      case ServerMsgDefs::SET_COLOR_MAP_ENTRIES:
        m_logWriter.detail(_T("Received message: SET_COLOR_MAP_ENTRIES"));
        receiveSetColorMapEntries();
        break;

      case ServerMsgDefs::BELL:
        m_logWriter.detail(_T("Received message: BELL"));
        receiveBell();
        break;

      case ServerMsgDefs::SERVER_CUT_TEXT:
        m_logWriter.detail(_T("Received message: SERVER_CUT_TEXT"));
        receiveServerCutText();
        break;

      default:
        if (m_serverMsgHandlers.find(msgType) != m_serverMsgHandlers.end()) {
          m_logWriter.detail(_T("Received message (%d) transmit to capability handler"), msgType);
          try {
            m_serverMsgHandlers[msgType]->onServerMessage(msgType, m_input);
          } catch (const Exception &ex) {
            m_logWriter.error(_T("Error in onServerMessage(): %s"), ex.getMessage());
          } catch (...) {
            m_logWriter.error(_T("Unknown error in onServerMessage()"));
          }
        } else {
          m_logWriter.error(_T("Server to client message: %d is not supported"), msgType);
        }
      }
    }
    StringStorage message(_T("Remote viewer's core thread terminated"));
    try {
      m_adapter->onDisconnect(&message);
    } catch (const Exception &ex) {
      m_logWriter.error(_T("Error in CoreEventsAdapter::onDisconnect(): %s"), ex.getMessage());
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onDisconnect()"));
    }

  } catch (const AuthException &ex) {
    m_logWriter.message(_T("RemoteVewerCore. Auth exception: %s"), ex.getMessage());
    try {
      m_adapter->onAuthError(&ex);
    } catch (const Exception &ex) {
      m_logWriter.error(_T("Error in CoreEventsAdapter::onAuthError(): %s"), ex.getMessage());
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onAuthError()"));
    }
  } catch (const IOException &ex) {
    try {
      StringStorage disconnectMessage(ex.getMessage());
      m_adapter->onDisconnect(&disconnectMessage);
    } catch (const Exception &ex) {
      m_logWriter.error(_T("Error in CoreEventsAdapter::onDisconnect(): %s"), ex.getMessage());
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onDisconnect()"));
    }
  } catch (const Exception &ex) {
    m_logWriter.message(_T("RemoteViewerCore. Exception: %s"), ex.getMessage());
    try {
      m_adapter->onError(&ex);
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onError()"));
    }
  } catch (...) {
    StringStorage error;
    error.format(_T("RemoteViewerCore. Unknown exception"));
    m_logWriter.message(_T("%s"), error.getString());
    Exception ex(error.getString());
    try {
      m_adapter->onError(&ex);
    } catch (...) {
      m_logWriter.error(_T("Unknown error in CoreEventsAdapter::onError()"));
    }
  }
}