public void TestResizeBitArrayBigger() { PrivateType hh = new PrivateType(typeof(HammingHelper)); BitArray bitArrayInput = new BitArray(10) { [0] = true, [2] = true, [8] = true, [9] = true, }; BitArray bitArrayExpected = new BitArray(18) { [0] = true, [2] = true, [8] = true, [9] = true, }; object[] args = { bitArrayInput, 18, 0 }; var bitArrayOutput = (BitArray)hh.InvokeStatic("ResizeBitArray", args); Assert.AreEqual(HammingHelper.BitArrayToDigitString(bitArrayExpected), HammingHelper.BitArrayToDigitString(bitArrayOutput)); }
private void btnInjectTypeError_Click(object sender, EventArgs e) { int errorNumber = 13; int numberOfBit = HammingHelper.GetTotalSize(HammingHelper.HammingDataSplitNumber); if (numErrorCorrectible.Validate()) { for (int i = (int)numErrorCorrectible.Value; i > 0; --i) { cable.InsertRandomErrors(1, errorNumber * numberOfBit, (errorNumber + 1) * numberOfBit); ++errorNumber; } } if (numErrorDetectable.Validate()) { for (int i = (int)numErrorDetectable.Value; i > 0; --i) { cable.InsertRandomErrors(2, errorNumber * numberOfBit, (errorNumber + 1) * numberOfBit); ++errorNumber; } } if (numIrrecoverable.Validate()) { for (int i = (int)numIrrecoverable.Value; i > 0; --i) { cable.InsertRandomErrors(3, errorNumber * numberOfBit, (errorNumber + 1) * numberOfBit); ++errorNumber; } } }
public void TestBitArrayToDigitString() { BitArray bitArray = new BitArray(5); Assert.AreEqual("00000", HammingHelper.BitArrayToDigitString(bitArray)); bitArray[0] = true; bitArray[2] = true; Assert.AreEqual("10100", HammingHelper.BitArrayToDigitString(bitArray)); bitArray.SetAll(true); Assert.AreEqual("11111", HammingHelper.BitArrayToDigitString(bitArray)); }
public void TestIsPowerOf2() { Assert.AreEqual(true, HammingHelper.IsPowerOf2(0)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(1)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(2)); Assert.AreEqual(false, HammingHelper.IsPowerOf2(3)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(4)); Assert.AreEqual(false, HammingHelper.IsPowerOf2(5)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(8)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(512)); Assert.AreEqual(true, HammingHelper.IsPowerOf2(1024)); Assert.AreEqual(false, HammingHelper.IsPowerOf2(1000)); }
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>(); }
/// <summary> /// Encode the frame and send it over to the transmitter. /// </summary> /// <param name="frame"></param> private void SendFrame(Frame frame) { // Prepare the frame to be sent on the wire (converts to BitArray and encode for error control with Hamming) BitArray frameBitArray = frame.GetFrameAsByteArray(); Tuple <BitArray, HammingHelper.Status> tuple = HammingHelper.EncryptManager(frameBitArray, CorrectionMode, EncodedFramePadding); BitArray encodedFrameBitArray = tuple.Item1; // Notify subscriber that frame is being sent sendFrameDelegate(frame, Constants.FrameEvent.FrameSent, StationId); Console.WriteLine("{4, 11} {0, 12} : id={1, 2}, type={2, 4}, ack={3, 2}, data lenght={5, 3}", "SendFrame", frame.Id, frame.Type.ToString(), frame.Ack, StationId == Constants.StationId.Station1 ? "Station 1" : "Station 2", frame.DataSize); // Send the data transmitter.SendData(encodedFrameBitArray, StationId); }
/// <summary> /// Get the frame from the transmitter. /// </summary> /// <returns>The decoded Frame. Null if Frame was corrupted or there was no data in the transmitter.</returns> private Frame GetReceivedFrame() { if (transmitter.DataReceived(StationId)) { // there is indeed a data, we are going to get it BitArray encodedFrameBitArray = transmitter.GetData(StationId); // Decode the frame Tuple <BitArray, HammingHelper.Status> tuple = HammingHelper.DecryptManager(encodedFrameBitArray, CorrectionMode, EncodedFramePadding); BitArray frameBitArray = tuple.Item1; // Keeps the current return type as the last received ones ReturnTypeOfLastReceivedFrame = tuple.Item2; // If Hamming detected an error, we return null because the frame is corrupted and Hamming did not fix it bool isCorrupted = tuple.Item2 == HammingHelper.Status.DETECTED; if (isCorrupted) { Console.WriteLine("corrupted frame received"); return(null); } // Converts BitArray to Frame Frame frame = Frame.GetFrameFromBitArray(frameBitArray); bool isInvalidFrame = frame.Id >= MaxSequence || !Enum.IsDefined(typeof(Constants.FrameType), (int)frame.Type) || frame.Ack >= MaxSequence || frame.DataSize > DataSizeInFrame || frame.Data.Count / 8 > DataSizeInFrame; if (isInvalidFrame) { Console.WriteLine("invalid frame received"); return(null); } Console.WriteLine("{4, 11} {0, 12} : id={1, 2}, type={2, 4}, ack={3, 2}, data lenght={5, 3}", "ReceiveFrame", frame.Id, frame.Type.ToString(), frame.Ack, StationId == Constants.StationId.Station1 ? "Station 1" : "Station 2", frame.DataSize); return(frame); } return(null); }
public void TestGetTotalSize() { Assert.AreEqual(13, HammingHelper.GetTotalSize(8)); Assert.AreEqual(26, HammingHelper.GetTotalSize(16)); }
public void TestGetDataSize() { Assert.AreEqual(8, HammingHelper.GetDataSize(13)); Assert.AreEqual(16, HammingHelper.GetDataSize(26)); }
public void TestEncryptDecryptManager() { // #1 case 10000010 (8 bits) BitArray bitArray = new BitArray(8) { [0] = true, [6] = true }; BitArray bitArrayEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT).Item1; BitArray bitArrayDecrypt = HammingHelper.DecryptManager(bitArrayEncrypt, HammingHelper.Mode.CORRECT).Item1; Assert.AreEqual(HammingHelper.BitArrayToDigitString(bitArray), HammingHelper.BitArrayToDigitString(bitArrayDecrypt)); // # Random case bitArray = new BitArray(32) { [0] = false, [6] = true, [8] = true, [18] = true, [20] = true, [29] = true, }; Tuple <BitArray, HammingHelper.Status> tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT); Tuple <BitArray, HammingHelper.Status> tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.CORRECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.OK, tupleDecrypt.Item2); Assert.AreEqual(HammingHelper.BitArrayToDigitString(bitArray), HammingHelper.BitArrayToDigitString(tupleDecrypt.Item1)); // # Random case with 1 error (CORRECTED) bitArray = new BitArray(8) { [0] = true, [3] = true, [5] = true, }; tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT); tupleEncrypt.Item1[9] = !tupleEncrypt.Item1[9]; // Inject error here tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.CORRECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.CORRECTED, tupleDecrypt.Item2); Assert.AreEqual(HammingHelper.BitArrayToDigitString(bitArray), HammingHelper.BitArrayToDigitString(tupleDecrypt.Item1)); // # Random case with 2 error (DETECTED) bitArray = new BitArray(8) { [0] = true, [3] = true, [5] = true, }; tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.DETECT); tupleEncrypt.Item1[1] = !tupleEncrypt.Item1[1]; // Inject error here tupleEncrypt.Item1[9] = !tupleEncrypt.Item1[9]; // Inject error here tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.DETECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.DETECTED, tupleDecrypt.Item2); // # Random case with 3 error (1 CORRECTED and 2 DETECTED) bitArray = new BitArray(16) { [0] = true, [1] = true, [5] = true, [7] = true, [13] = true, }; tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT); tupleEncrypt.Item1[1] = !tupleEncrypt.Item1[1]; // Inject error here (first 13 bits) tupleEncrypt.Item1[20] = !tupleEncrypt.Item1[20]; // Inject error here (second 13 bits) tupleEncrypt.Item1[25] = !tupleEncrypt.Item1[25]; // Inject error here (second 13 bits) tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.CORRECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.DETECTED, tupleDecrypt.Item2); // # Random case with 3 error (NOT SUPPORTED) bitArray = new BitArray(8) { [0] = true, [1] = true, [5] = true, }; tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT); tupleEncrypt.Item1[1] = !tupleEncrypt.Item1[1]; // Inject error here tupleEncrypt.Item1[5] = !tupleEncrypt.Item1[5]; // Inject error here tupleEncrypt.Item1[9] = !tupleEncrypt.Item1[9]; // Inject error here tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.CORRECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.DETECTED, tupleDecrypt.Item2); // # Random case with 1 (Detect only 1 bit) bitArray = new BitArray(8) { [0] = true, [1] = true, [5] = true, }; tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.DETECT); tupleEncrypt.Item1[1] = !tupleEncrypt.Item1[1]; // Inject error here tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.DETECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.DETECTED, tupleDecrypt.Item2); // # Brute force cases for (int num = 0; num < 256; ++num) { for (int i = 0; i < 13; ++i) { for (int j = 0; j < 13; ++j) { if (i == j) { continue; } byte[] bytes = BitConverter.GetBytes(num); bitArray = new BitArray(new[] { bytes[0] }); tupleEncrypt = HammingHelper.EncryptManager(bitArray, HammingHelper.Mode.CORRECT); tupleEncrypt.Item1[j] = !tupleEncrypt.Item1[j]; // Inject error here tupleEncrypt.Item1[i] = !tupleEncrypt.Item1[i]; // Inject error here tupleDecrypt = HammingHelper.DecryptManager(tupleEncrypt.Item1, HammingHelper.Mode.CORRECT); Assert.AreEqual(HammingHelper.Status.OK, tupleEncrypt.Item2); Assert.AreEqual(HammingHelper.Status.DETECTED, tupleDecrypt.Item2); } } } }