Beispiel #1
0
        /// <summary>
        /// Call this function if a list of commands has been arrived from the given operator in the given frame.
        /// </summary>
        /// <param name="theCommands">List of the arrived commands.</param>
        /// <param name="opIdx">The index of the sender operator.</param>
        /// <param name="frameIdx">The index of the frame of the commands.</param>
        /// <returns>True in case of success, false otherwise.</returns>
        public bool Command(RCPackage[] theCommands, int opIdx, int frameIdx)
        {
            if (theCommands == null || theCommands.Length == 0)
            {
                throw new ArgumentNullException("theCommands");
            }
            if (opIdx < 0 || opIdx >= this.commitFlags.Length)
            {
                throw new ArgumentOutOfRangeException("opIdx");
            }
            if (frameIdx < 0 || frameIdx >= this.simulatorCommands.Length)
            {
                throw new ArgumentOutOfRangeException("frameNum");
            }

            for (int i = 0; i < theCommands.Length; i++)
            {
                if (theCommands[i] == null || !theCommands[i].IsCommitted ||
                    theCommands[i].PackageType != RCPackageType.CUSTOM_DATA_PACKAGE ||
                    DssRoot.IsInternalFormat(theCommands[i].PackageFormat))
                {
                    return(false);
                }
            }

            if (this.initialized)
            {
                if (!this.commitFlags[opIdx])
                {
                    if (this.simulatorCommands[frameIdx][opIdx] == null)
                    {
                        this.simulatorCommands[frameIdx][opIdx] = theCommands;
                        return(true);
                    }
                    else
                    {
                        /// Command list has been already sent by the given operator for the given frame.
                        return(false);
                    }
                }
                else
                {
                    /// The round has been already committed by the sender operator --> error.
                    return(false);
                }
            }
            else
            {
                throw new DssException("Uninitialized SimulationRound!");
            }
        }
Beispiel #2
0
        /// <summary>
        /// Creates an answer to the current setup step at guest side.
        /// </summary>
        /// <param name="outgoingPackages">The outgoing packages sent by the client module.</param>
        /// <returns>List of the packages of the outgoing setup step answer.</returns>
        /// <remarks>This function must be called at guest side.</remarks>
        public RCPackage[] CreateAnswer(RCPackage[] outgoingPackages)
        {
            if (this.mode != DssMode.GUEST_SIDE)
            {
                throw new DssException("This call is only allowed at guest side!");
            }
            if (this.state != SetupStepState.READY)
            {
                throw new DssException("You can only create answer in READY state!");
            }
            if (outgoingPackages == null)
            {
                throw new ArgumentNullException("outgoingPackages");
            }

            int numPackages = outgoingPackages.Length + 2; /// BEGIN, END

            RCPackage[] retList = new RCPackage[numPackages];
            for (int i = 0; i < numPackages; i++)
            {
                if (i == 0)         /// BEGIN
                {
                    retList[i] = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_SETUP_STEP_AW_BEGIN);
                    retList[i].WriteInt(0, this.stepID);
                }
                else if (i == numPackages - 1)  /// END
                {
                    retList[i] = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_SETUP_STEP_MSG_END);
                    retList[i].WriteInt(0, this.stepID);
                }
                else    /// Package from the client module
                {
                    if (outgoingPackages[i - 1] != null && outgoingPackages[i - 1].IsCommitted &&
                        outgoingPackages[i - 1].PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                        !DssRoot.IsInternalFormat(outgoingPackages[i - 1].PackageFormat))
                    {
                        retList[i] = outgoingPackages[i - 1];
                    }
                    else
                    {
                        throw new DssException("Outgoing setup package format error!");
                    }
                }
            } /// end-for

            return(retList);
        }
        /// <summary>
        /// Internal function to timestamp and send the given commands to the lobby.
        /// </summary>
        /// <param name="cmds">The list of the commands to send.</param>
        private void SendCommandsToLobby(RCPackage[] cmds)
        {
            if (!this.initialized)
            {
                throw new DssException("DssSimulationMgr is uninitialized!");
            }
            if (cmds != null && cmds.Length != 0)
            {
                /// Compute the length of the buffer needed for sending the commands as a byte sequence
                int bufferLength = 0;
                for (int i = 0; i < cmds.Length; i++)
                {
                    if (cmds[i] != null && cmds[i].IsCommitted && cmds[i].PackageType == RCPackageType.CUSTOM_DATA_PACKAGE &&
                        !DssRoot.IsInternalFormat(cmds[i].PackageFormat))
                    {
                        bufferLength += cmds[i].PackageLength;
                    }
                    else
                    {
                        throw new DssException("Unexpected command from the client module!");
                    }
                }

                /// Create the buffer and write the commands into this buffer
                byte[] cmdBuffer = new byte[bufferLength];
                int    offset    = 0;
                for (int i = 0; i < cmds.Length; i++)
                {
                    offset += cmds[i].WritePackageToBuffer(cmdBuffer, offset);
                }

                /// Create the DSS_COMMAND package and send it to the lobby
                RCPackage cmdPackage = RCPackage.CreateNetworkCustomPackage(DssRoot.DSS_COMMAND);
                cmdPackage.WriteInt(0, this.nextNextRound.RoundIndex);       /// Round index of the command
                cmdPackage.WriteInt(1, this.currentRound.CurrentFrameIndex); /// Frame index of the command
                cmdPackage.WriteByteArray(2, cmdBuffer);                     /// The command list

                this.root.LobbyIface.SendPackage(cmdPackage);                /// Send the command package to the lobby
            }
        }
Beispiel #4
0
        /// <summary>
        /// Starts a new setup step at host side.
        /// </summary>
        /// <param name="outgoingPackages">The outgoing packages sent by the client module.</param>
        /// <param name="leftList">List of the guests that left or were dropped from the DSS.</param>
        /// <param name="lostList">List of the guests that the host left connection with.</param>
        /// <param name="channelStates">The current state of the channels.</param>
        /// <returns>List of the packages of the outgoing setup step request.</returns>
        /// <remarks>This function must be called at host side.</remarks>
        public RCPackage[] CreateRequest(RCPackage[] outgoingPackages,
                                         int[] leftList,
                                         int[] lostList,
                                         DssChannelState[] channelStates)
        {
            if (this.mode != DssMode.HOST_SIDE)
            {
                throw new DssException("This call is only allowed at host side!");
            }
            if (this.state != SetupStepState.NOT_FINISHED)
            {
                throw new DssException("Invalid setup step state!");
            }
            if (channelStates == null || channelStates.Length < 1)
            {
                throw new ArgumentNullException("channelStates");
            }
            if (outgoingPackages == null)
            {
                throw new ArgumentNullException("outgoingPackages");
            }

            int numPackages = outgoingPackages.Length + 2; /// BEGIN, END

            RCPackage[] retList = new RCPackage[numPackages];
            for (int i = 0; i < numPackages; i++)
            {
                if (i == 0)         /// BEGIN
                {
                    retList[i] = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_SETUP_STEP_RQ_BEGIN);
                    retList[i].WriteInt(0, this.stepID);
                    retList[i].WriteIntArray(1, leftList != null ? leftList : new int[0] {
                    });
                    retList[i].WriteIntArray(2, lostList != null ? lostList : new int[0] {
                    });
                    byte[] stateBytes = new byte[channelStates.Length];
                    for (int j = 0; j < channelStates.Length; j++)
                    {
                        stateBytes[j] = (byte)channelStates[j];
                    }
                    retList[i].WriteByteArray(3, stateBytes);
                }
                else if (i == numPackages - 1)  /// END
                {
                    retList[i] = RCPackage.CreateNetworkControlPackage(DssRoot.DSS_CTRL_SETUP_STEP_MSG_END);
                    retList[i].WriteInt(0, this.stepID);
                }
                else    /// Package from the client module
                {
                    if (outgoingPackages[i - 1] != null && outgoingPackages[i - 1].IsCommitted &&
                        outgoingPackages[i - 1].PackageType == RCPackageType.NETWORK_CONTROL_PACKAGE &&
                        !DssRoot.IsInternalFormat(outgoingPackages[i - 1].PackageFormat))
                    {
                        retList[i] = outgoingPackages[i - 1];
                    }
                    else
                    {
                        throw new DssException("Outgoing setup package format error!");
                    }
                }
            } /// end-for

            return(retList);
        }
Beispiel #5
0
        /// <summary>
        /// Call this function if a control package has arrived from the network and you are waiting for a setup step
        /// answer or request. This class will parse it for you automatically.
        /// </summary>
        /// <param name="package">The incoming control package.</param>
        public void IncomingPackage(RCPackage package)
        {
            if (package == null)
            {
                throw new ArgumentNullException("package");
            }
            if (!package.IsCommitted)
            {
                throw new ArgumentException("Uncommitted package!", "package");
            }
            if (package.PackageType != RCPackageType.NETWORK_CONTROL_PACKAGE)
            {
                throw new ArgumentException("Unexpected package type!", "package");
            }
            if (this.state != SetupStepState.NOT_FINISHED)
            {
                throw new DssException("This call is only allowed in NOT_FINISHED state!");
            }

            if (this.mode == DssMode.HOST_SIDE)
            {
                /// Host side parsing
                if (this.beginArrived)
                {
                    if (!DssRoot.IsInternalFormat(package.PackageFormat))
                    {
                        this.packageListTmp.Add(package);
                    }
                    else
                    {
                        if (package.PackageFormat.ID == DssRoot.DSS_CTRL_SETUP_STEP_MSG_END &&
                            package.ReadInt(0) == this.stepID)
                        {
                            /// Finished
                            this.packageList = this.packageListTmp.ToArray();
                            this.state       = SetupStepState.READY;
                        }
                        else
                        {
                            /// Error
                            this.state = SetupStepState.ERROR;
                        }
                    }
                }
                else /// end-if (this.beginArrived)
                {
                    if (package.PackageFormat.ID == DssRoot.DSS_CTRL_SETUP_STEP_AW_BEGIN &&
                        package.ReadInt(0) == this.stepID)
                    {
                        this.beginArrived = true;
                    }
                    else
                    {
                        /// Error
                        this.state = SetupStepState.ERROR;
                    }
                }
            }
            else /// end-if (this.mode == SetupStepMode.HOST_SIDE)
            {
                /// Guest side parsing
                if (this.beginArrived)
                {
                    if (!DssRoot.IsInternalFormat(package.PackageFormat))
                    {
                        this.packageListTmp.Add(package);
                    }
                    else
                    {
                        if (package.PackageFormat.ID == DssRoot.DSS_CTRL_SETUP_STEP_MSG_END &&
                            package.ReadInt(0) == this.stepID)
                        {
                            /// Finished
                            this.packageList = this.packageListTmp.ToArray();
                            this.state       = SetupStepState.READY;
                        }
                        else
                        {
                            /// Error
                            this.state = SetupStepState.ERROR;
                        }
                    }
                }
                else /// end-if (this.beginArrived)
                {
                    if (package.PackageFormat.ID == DssRoot.DSS_CTRL_SETUP_STEP_RQ_BEGIN)
                    {
                        /// Read the step ID
                        this.stepID = package.ReadInt(0);

                        /// Read the left-list
                        int[] leftList = package.ReadIntArray(1);
                        bool  err      = false;
                        for (int i = 0; i < leftList.Length; ++i)
                        {
                            if (leftList[i] < 0)
                            {
                                err = true;
                                break;
                            }
                        }
                        if (!err)
                        {
                            /// OK, save the list
                            this.leftList = leftList;
                        }
                        else
                        {
                            /// Error
                            this.state = SetupStepState.ERROR;
                            return;
                        }

                        /// Read the lost-list
                        int[] lostList = package.ReadIntArray(2);
                        err = false;
                        for (int i = 0; i < lostList.Length; ++i)
                        {
                            if (lostList[i] < 0)
                            {
                                err = true;
                                break;
                            }
                        }
                        if (!err)
                        {
                            /// OK, save the list
                            this.lostList = lostList;
                        }
                        else
                        {
                            /// Error
                            this.state = SetupStepState.ERROR;
                            return;
                        }

                        /// Read the channel-state-list
                        byte[] chStateBytes = package.ReadByteArray(3);
                        if (chStateBytes.Length != 0)
                        {
                            this.channelStateList = new DssChannelState[chStateBytes.Length];
                            for (int i = 0; i < chStateBytes.Length; ++i)
                            {
                                if (chStateBytes[i] == (byte)DssChannelState.CHANNEL_CLOSED ||
                                    chStateBytes[i] == (byte)DssChannelState.CHANNEL_OPENED ||
                                    chStateBytes[i] == (byte)DssChannelState.GUEST_CONNECTED)
                                {
                                    this.channelStateList[i] = (DssChannelState)chStateBytes[i];
                                }
                                else
                                {
                                    /// Error
                                    this.state = SetupStepState.ERROR;
                                    return;
                                }
                            }
                        } /// end-if (chStateBytes != null && chStateBytes.Length != 0)
                        else
                        {
                            /// Error
                            this.state = SetupStepState.ERROR;
                            return;
                        }

                        /// Everything is OK, the begin message arrived successfully.
                        this.beginArrived = true;
                    }
                    else /// end-if (package.PackageFormat.ID == DssRoot.DSS_CTRL_SETUP_STEP_RQ_BEGIN)
                    {
                        /// Error
                        this.state = SetupStepState.ERROR;
                    }
                }
            }
        }