public void ParityErrorOnLastByte() { using (var com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) using (var com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) { var rndGen = new Random(15); var bytesToWrite = new byte[numRndByte]; var expectedBytes = new byte[numRndByte]; var actualBytes = new byte[numRndByte + 1]; var actualByteIndex = 0; /* 1 Additional character gets added to the input buffer when the parity error occurs on the last byte of a stream * We are verifying that besides this everything gets read in correctly. See NDP Whidbey: 24216 for more info on this */ Debug.WriteLine("Verifying default ParityReplace byte with a parity error on the last byte"); // Generate random characters without an parity error for (var i = 0; i < bytesToWrite.Length; i++) { var randByte = (byte)rndGen.Next(0, 128); bytesToWrite[i] = randByte; expectedBytes[i] = randByte; } bytesToWrite[bytesToWrite.Length - 1] = (byte)(bytesToWrite[bytesToWrite.Length - 1] | 0x80); // Create a parity error on the last byte expectedBytes[expectedBytes.Length - 1] = com1.ParityReplace; // Set the last expected byte to be the ParityReplace Byte com1.Parity = Parity.Space; com1.DataBits = 7; com1.ReadTimeout = 250; com1.Open(); com2.Open(); com2.Write(bytesToWrite, 0, bytesToWrite.Length); TCSupport.WaitForReadBufferToLoad(com1, bytesToWrite.Length + 1); while (true) { int byteRead; try { byteRead = com1.ReadByte(); } catch (TimeoutException) { break; } actualBytes[actualByteIndex] = (byte)byteRead; actualByteIndex++; } // Compare the chars that were written with the ones we expected to read for (var i = 0; i < expectedBytes.Length; i++) { if (expectedBytes[i] != actualBytes[i]) { Fail("ERROR!!!: Expected to read {0} actual read {1}", (int)expectedBytes[i], (int)actualBytes[i]); } } if (1 < com1.BytesToRead) { Fail("ERROR!!!: Expected BytesToRead=0 actual={0}", com1.BytesToRead); Fail("ByteRead={0}, {1}", com1.ReadByte(), bytesToWrite[bytesToWrite.Length - 1]); } bytesToWrite[bytesToWrite.Length - 1] = (byte)(bytesToWrite[bytesToWrite.Length - 1] & 0x7F); // Clear the parity error on the last byte expectedBytes[expectedBytes.Length - 1] = bytesToWrite[bytesToWrite.Length - 1]; VerifyRead(com1, com2, bytesToWrite, expectedBytes, Encoding.ASCII); } }
private void VerifyStopBits(SerialPort com1) { Random rndGen = new Random(-55); Stopwatch sw = new Stopwatch(); using (SerialPort com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) { double expectedTime, actualTime, percentageDifference; int numBytes = 0; byte shiftMask = 0xFF; double stopBits = -1; switch ((int)com1.StopBits) { case (int)StopBits.One: stopBits = 1.0; break; case (int)StopBits.OnePointFive: stopBits = 1.5; break; case (int)StopBits.Two: stopBits = 2.0; break; } int numBytesToSend = (int)(((DEFAULT_TIME / 1000.0) * com1.BaudRate) / (stopBits + com1.DataBits + 1)); byte[] xmitBytes = new byte[numBytesToSend]; byte[] expectedBytes = new byte[numBytesToSend]; byte[] rcvBytes = new byte[numBytesToSend]; //Create a mask that when logicaly and'd with the transmitted byte will //will result in the byte recievied due to the leading bits being chopped //off due to DataBits less then 8 shiftMask >>= 8 - com1.DataBits; //Generate some random bytes to read/write for this StopBits setting for (int i = 0; i < xmitBytes.Length; i++) { xmitBytes[i] = (byte)rndGen.Next(0, 256); expectedBytes[i] = (byte)(xmitBytes[i] & shiftMask); } com2.DataBits = com1.DataBits; com2.StopBits = com1.StopBits; com2.Open(); actualTime = 0; Thread.CurrentThread.Priority = ThreadPriority.Highest; int initialNumBytes; for (int i = 0; i < NUM_TRYS; i++) { com2.DiscardInBuffer(); IAsyncResult beginWriteResult = com1.BaseStream.BeginWrite(xmitBytes, 0, numBytesToSend, null, null); while (0 == (initialNumBytes = com2.BytesToRead)) { } sw.Start(); TCSupport.WaitForReadBufferToLoad(com2, numBytesToSend); sw.Stop(); actualTime += sw.ElapsedMilliseconds; actualTime += ((initialNumBytes * (stopBits + com1.DataBits + 1)) / com1.BaudRate) * 1000; com1.BaseStream.EndWrite(beginWriteResult); sw.Reset(); } Thread.CurrentThread.Priority = ThreadPriority.Normal; actualTime /= NUM_TRYS; expectedTime = ((xmitBytes.Length * (stopBits + com1.DataBits + 1)) / com1.BaudRate) * 1000; percentageDifference = Math.Abs((expectedTime - actualTime) / expectedTime); //If the percentageDifference between the expected time and the actual time is to high //then the expected baud rate must not have been used and we should report an error if (MAX_ACCEPTABEL_PERCENTAGE_DIFFERENCE < percentageDifference) { Fail("ERROR!!! StopBits not used Expected time:{0}, actual time:{1} percentageDifference:{2}", expectedTime, actualTime, percentageDifference, numBytes); } com2.Read(rcvBytes, 0, rcvBytes.Length); //Verify that the bytes we sent were the same ones we received for (int i = 0; i < expectedBytes.Length; i++) { if (expectedBytes[i] != rcvBytes[i]) { Fail("ERROR!!! Expected to read {0} actual read {1}", expectedBytes[i], rcvBytes[i]); } } } }
private void Verify_Handshake(Handshake handshake) { using (SerialPort com1 = new SerialPort(TCSupport.LocalMachineSerialInfo.FirstAvailablePortName)) using (SerialPort com2 = new SerialPort(TCSupport.LocalMachineSerialInfo.SecondAvailablePortName)) { byte[] XOffBuffer = new byte[1]; byte[] XOnBuffer = new byte[1]; XOffBuffer[0] = 19; XOnBuffer[0] = 17; int numNewLineBytes; Debug.WriteLine("Verifying Handshake={0}", handshake); com1.WriteTimeout = 3000; com1.Handshake = handshake; com1.Open(); com2.Open(); numNewLineBytes = com1.Encoding.GetByteCount(com1.NewLine.ToCharArray()); //Setup to ensure write will block with type of handshake method being used if (Handshake.RequestToSend == handshake || Handshake.RequestToSendXOnXOff == handshake) { com2.RtsEnable = false; } if (Handshake.XOnXOff == handshake || Handshake.RequestToSendXOnXOff == handshake) { com2.Write(XOffBuffer, 0, 1); Thread.Sleep(250); } //Write a random string asynchronously so we can verify some things while the write call is blocking string randomLine = TCSupport.GetRandomString(s_STRING_SIZE_HANDSHAKE, TCSupport.CharacterOptions.Surrogates); byte[] randomLineBytes = com1.Encoding.GetBytes(randomLine); Task task = Task.Run(() => com1.WriteLine(randomLine)); TCSupport.WaitForTaskToStart(task); TCSupport.WaitForWriteBufferToLoad(com1, randomLineBytes.Length + numNewLineBytes); //Verify that CtsHolding is false if the RequestToSend or RequestToSendXOnXOff handshake method is used if ((Handshake.RequestToSend == handshake || Handshake.RequestToSendXOnXOff == handshake) && com1.CtsHolding) { Fail("ERROR!!! Expcted CtsHolding={0} actual {1}", false, com1.CtsHolding); } //Setup to ensure write will succeed if (Handshake.RequestToSend == handshake || Handshake.RequestToSendXOnXOff == handshake) { com2.RtsEnable = true; } if (Handshake.XOnXOff == handshake || Handshake.RequestToSendXOnXOff == handshake) { com2.Write(XOnBuffer, 0, 1); } //Wait till write finishes TCSupport.WaitForTaskCompletion(task); Assert.Equal(0, com1.BytesToWrite); //Verify that CtsHolding is true if the RequestToSend or RequestToSendXOnXOff handshake method is used if ((Handshake.RequestToSend == handshake || Handshake.RequestToSendXOnXOff == handshake) && !com1.CtsHolding) { Fail("ERROR!!! Expected CtsHolding={0} actual {1}", true, com1.CtsHolding); } } }