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()")); } } }