public Station( Constants.StationId stationType, ITransmitter transmitter, int bufferSize, int timeoutInMs, bool detectionOnly, FileStream inputFileStream, FileStream outputFileStream, Constants.ShowFrameDelegate sendFrame) { this.StationId = stationType; this.transmitter = transmitter; this.BufferSize = bufferSize; InputBuffer = new Dictionary <int, Frame>(); OutputBuffer = new Dictionary <int, Frame>(); this.TimeoutInMs = timeoutInMs; this.CorrectionMode = detectionOnly ? HammingHelper.Mode.DETECT : HammingHelper.Mode.CORRECT; this.inputFileStream = inputFileStream; this.outputFileStream = outputFileStream; this.sendFrameDelegate = sendFrame; StopExecution = false; ExecutionStopped = new ManualResetEvent(false); // Initialize constants int frameSizeBeforeHamming = HammingHelper.GetDataSize(Constants.FrameSize * 8) / 8; int realBitCount = HammingHelper.GetTotalSize(frameSizeBeforeHamming * 8); EncodedFramePadding = Constants.FrameSize * 8 - realBitCount; int frameHeaderSize = Frame.HeaderSize(); DataSizeInFrame = frameSizeBeforeHamming - frameHeaderSize; MaxSequence = (UInt16)(bufferSize * 2 - 1); // Initialize fields FirstFrameSent = 0; NextFrameToSendSequenceNumber = 0; NextFrameToReceive = 0; // Since frames cannot use MaxSequence as a sequence number, we use it for LastFrameSequenceNumberForNak. // This is meant to ensure that no Frame matches this field if there was no Nak sent. LastFrameSequenceNumberForNak = MaxSequence; // Initialise ack timer logic AckTimer = new System.Timers.Timer(AckTimeout); // When the timer ends, we need to inform the program that we need to send an Ack now. Also stop the timer. AckTimer.Elapsed += (sender, e) => { sendAck = true; AckTimer.Stop(); Console.WriteLine("ack timer elapsed"); }; sendAck = false; HighPriorityFrames = new Queue <Frame>(); TimeoutTimers = new ConcurrentDictionary <UInt16, System.Timers.Timer>(); }
private void ShowFrame(Frame frameToShow, Constants.FrameEvent frameEvent, Constants.StationId stationId) { bool isSent = frameEvent == Constants.FrameEvent.FrameSent; //based on msdn doc: https://msdn.microsoft.com/en-us/library/ms171728(v=vs.110).aspx //Thread safe call to richtextbox RichTextBox textBox = isSent ? txtDataSend : txtReception; if (textBox.InvokeRequired) { UpdateDataDelegate d = ShowFrame; Invoke(d, frameToShow, frameEvent, stationId); } else { OnAppend(((Int16)frameToShow.Id).ToString("000") + " | ", textBox, DefaultForeColor); switch (frameToShow.Type) { case Constants.FrameType.Ack: OnAppend("Ack ", textBox, Color.Green); break; case Constants.FrameType.Nak: OnAppend("Nak ", textBox, Color.DarkRed); break; case Constants.FrameType.Data: OnAppend("Data", textBox, DefaultForeColor); break; } OnAppend(" | " + ((Int16)frameToShow.Ack).ToString("00"), textBox, DefaultForeColor); OnAppend(" | " + frameToShow.DataSize.ToString("000"), textBox, DefaultForeColor); OnAppend(" ", textBox, DefaultForeColor); string errorMessage = "|"; Color errorColor = DefaultForeColor; switch (frameEvent) { case Constants.FrameEvent.FrameReceivedCorrupted: errorMessage += "Détecté"; errorColor = Color.DarkOrange; break; case Constants.FrameEvent.FrameReceivedNotAwaited: break; case Constants.FrameEvent.FrameReceivedDuplicate: break; case Constants.FrameEvent.FrameReceivedOk: break; case Constants.FrameEvent.FrameReceivedCorrected: errorMessage += "Corrigé"; errorColor = Color.DarkGreen; break; case Constants.FrameEvent.FrameSent: break; default: throw new ArgumentOutOfRangeException(nameof(frameEvent), frameEvent, null); } OnAppend(errorMessage, textBox, errorColor); OnAppend(Environment.NewLine, textBox, DefaultForeColor); //Updating the progress bar. if (stationId == Constants.StationId.Station2 && (frameEvent == Constants.FrameEvent.FrameReceivedOk || frameEvent == Constants.FrameEvent.FrameReceivedCorrected)) { int newTotal = transfertBar.Value + (int)frameToShow.DataSize; transfertBar.Value = Math.Min(newTotal, transfertBar.Maximum); if (transfertBar.Value == transfertBar.Maximum) { MessageBox.Show(this, "Tranfert complété!"); } } } }