/// <summary> /// Called when a control packages arrived from the host during setup stage. /// </summary> /// <param name="package">The arrived control package.</param> public void SetupStageCtrlPackage(RCPackage package) { if (this.sm.CurrentState == this.WaitingConnectionACK) { if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_ACK) { int otherMajor = package.ReadInt(0); int otherMinor = package.ReadInt(1); int otherBuild = package.ReadInt(2); int otherRevision = package.ReadInt(3); if (otherMajor >= 0 && otherMinor >= 0 && otherBuild >= 0 && otherRevision >= 0) { Version otherVer = new Version(otherMajor, otherMinor, otherBuild, otherRevision); if (DssRoot.IsCompatibleVersion(otherVer)) { this.WaitingConnectionACK_WaitingSetupStepRQ.Fire(); this.controller.ExecuteFirings(); return; } else { TraceManager.WriteAllTrace(string.Format("Incompatible with host version: {0} (RC.DssServices)", otherVer), DssTraceFilters.SETUP_STAGE_ERROR); SetupStageError(); return; } } else { TraceManager.WriteAllTrace("Unable to parse version information!", DssTraceFilters.SETUP_STAGE_ERROR); SetupStageError(); return; } } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_ACK) else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REJECT) { TraceManager.WriteAllTrace(string.Format("Connection request rejected by the host! Reason: {0}", package.ReadString(0)), DssTraceFilters.SETUP_STAGE_ERROR); SetupStageError(); return; } else { TraceManager.WriteAllTrace("Unexpected answer from host to connection request!", DssTraceFilters.SETUP_STAGE_ERROR); SetupStageError(); return; } } else if (this.sm.CurrentState == this.WaitingSetupStepRQ) { if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) { /// The host left the DSS this.guestRoot.SetupIface.HostLeftDss(); StopTimeouts(); this.guestRoot.EventQueue.ExitEventLoop(); return; } /// end-if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_DROP_GUEST) { /// The current guest has been dropped out of the DSS by the host. this.guestRoot.SetupIface.DroppedByHost(); StopTimeouts(); this.guestRoot.EventQueue.ExitEventLoop(); return; } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_DROP_GUEST) else if (package.PackageFormat.ID == DssRoot.DSS_CTRL_START_SIMULATION) { int[] leftList = null; int[] lostList = null; bool[] opFlags = null; if (ParseStartSimPackage(package, out leftList, out lostList, out opFlags)) { StopTimeouts(); CallNotificationMethods(leftList, lostList); this.guestRoot.SetupIface.SimulationStarted(); this.opFlagsTmp = opFlags; this.WaitingSetupStepRQ_Simulating.Fire(); this.controller.ExecuteFirings(); return; } else { SetupStageError(); return; } } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_START_SIMULATION) else { this.guestRoot.Step.IncomingPackage(package); if (this.guestRoot.Step.State == SetupStepState.READY) { /// Setup step request arrived. this.WaitingSetupStepRQ_SendingSetupStepAW.Fire(); this.controller.ExecuteFirings(); return; } else if (this.guestRoot.Step.State == SetupStepState.ERROR) { /// Setup step request error. SetupStageError(); return; } else { /// Setup step request not finished yet, more packages to wait. return; } } } /// end-if (this.sm.CurrentState == this.WaitingSetupStepRQ) else { /// Go to error state if the package cannot be handled until now. SetupStageError(); return; } }
/// <summary> /// This function is called when a control package arrives at setup stage. /// </summary> /// <param name="package">The arrived control package.</param> public void SetupStageCtrlPackage(RCPackage package) { bool error = false; if (this.sm.CurrentState == this.WaitingConnectionRQ) { if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST) { RCPackage rejPackage = null; int otherMajor = package.ReadInt(0); int otherMinor = package.ReadInt(1); int otherBuild = package.ReadInt(2); int otherRevision = package.ReadInt(3); if (otherMajor >= 0 && otherMinor >= 0 && otherBuild >= 0 && otherRevision >= 0) { Version otherVer = new Version(otherMajor, otherMinor, otherBuild, otherRevision); if (DssRoot.IsCompatibleVersion(otherVer)) { /// We send back a DSS_CTRL_CONN_ACK package. RCPackage ackPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_ACK); ackPackage.WriteInt(0, DssRoot.APPLICATION_VERSION.Major); ackPackage.WriteInt(1, DssRoot.APPLICATION_VERSION.Minor); ackPackage.WriteInt(2, DssRoot.APPLICATION_VERSION.Build); ackPackage.WriteInt(3, DssRoot.APPLICATION_VERSION.Revision); this.manager.HostRoot.Lobby.SendControlPackage(ackPackage, this.channel.Index + 1); this.WaitingConnectionRQ_SendingSetupStepRQ.Fire(); } else { /// We send back a DSS_CTRL_CONN_REJECT package rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT); string reason = string.Format("Incompatible with host version: {0} (RC.DssServices)", DssRoot.APPLICATION_VERSION.ToString()); rejPackage.WriteString(0, reason); rejPackage.WriteByteArray(1, new byte[0]); } } else { /// We create a DSS_CTRL_CONN_REJECT package rejPackage = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_CONN_REJECT); rejPackage.WriteString(0, "Unable to parse version information!"); rejPackage.WriteByteArray(1, new byte[0]); } /// We send back a DSS_CTRL_CONN_REJECT package if necessary. if (rejPackage != null && rejPackage.IsCommitted) { this.manager.HostRoot.Lobby.SendControlPackage(rejPackage, this.channel.Index + 1); error = true; } } /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_CONN_REQUEST) } /// end-if (this.sm.CurrentState == this.WaitingConnectionRQ) else if (this.sm.CurrentState == this.WaitingSetupStepAW) { if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) { string leaveReason = package.ReadString(0); string trcMsg = string.Format("Guest-{0} has left the DSS. Reason: {1}", this.channel.Index, leaveReason.Length != 0 ? leaveReason : "-"); TraceManager.WriteAllTrace(trcMsg, DssTraceFilters.SETUP_STAGE_INFO); this.WaitingSetupStepAW_Inactive.Fire(); this.channel.GuestLeaveSetupStage(); } /// end-if (package.PackageFormat.ID == DssRoot.DSS_LEAVE) else { SetupStep currentStep = this.manager.HostRoot.GetStep(this.channel.Index); currentStep.IncomingPackage(package); if (currentStep.State == SetupStepState.READY) { /// Setup step answer arrived. this.WaitingSetupStepAW_SendingSetupStepRQ.Fire(); } else if (currentStep.State == SetupStepState.ERROR) { /// Setup step answer error. error = true; } else { /// Setup step answer not finished yet, more packages to wait. } } } /// end-if (this.sm.CurrentState == this.WaitingSetupStepAW) if (error) { /// Go to error state if the package cannot be handled until now. SetupStageError(); this.channel.SetupStageError(); return; } }