📄 rs232noise.cpp
字号:
// RS232Noise.cpp: implementation of the CRS232Noise class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "RS232Noise.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRS232Noise::CRS232Noise()
{
SetErrorTypes(FALSE, 0); // set for no errors
m_nukedPort = FALSE;
reserved = 0x5555AAAA;
}
CRS232Noise::~CRS232Noise()
{
}
// --------------------------------- SetErrorTypes -----------------------
void CRS232Noise::SetErrorTypes(BOOL enable,
LONG freq,
LONG period,
BOOL inserts ,
BOOL removes ,
BOOL misFrames , // off by default
BOOL corrupts,
BOOL ignore,
BOOL parityFaults,
BOOL beep
)
{
m_enableFaults = enable;
m_insertCharacters = inserts;
m_removeCharacters = removes;
m_corruptFraming = misFrames;
m_modifyCharacters = corrupts;
m_errorFrequency = freq;
m_ignoreReq = ignore;
m_delaysPeriod = period;
m_parityFaults = parityFaults;
//
m_errorsInjected = 0;
m_beep = beep;
} // SetErrorTypes
// ------------------------------- GetErrorTypes ----------------------
void CRS232Noise::GetErrorTypes(BOOL *enable,
int *freq,
int *period, // delays by (0=disable)
BOOL *inserts,
BOOL *removes,
BOOL *misFrames,
BOOL *corrupts,
BOOL *ignore,
BOOL *parity,
BOOL *beep
)
{
*enable = m_enableFaults;
*inserts = m_insertCharacters;
*removes = m_removeCharacters;
*misFrames = m_corruptFraming;
*corrupts = m_modifyCharacters;
*freq = m_errorFrequency;
*ignore = m_ignoreReq;
*period = m_delaysPeriod;
*parity = m_parityFaults;
//
*beep = m_beep;
} // GetErrorTypes
// ---------------------------------------- InjectErrors ----------------------
LONG CRS232Noise::InjectErrors(CRS232Port *pPort,
const BYTE *transmitBuffer,
int writeLength,
char*pDebugStr)
{
BYTE *pBuffer, *pBufferPtr;
int bufferIndex; // index into the un-corrupted data
int randN, faultType, faultPercent; // random values
int len; // length of data to send in a burst.
LONG retValue;
CString ErrorDescription;
BYTE chErr;
if (!m_enableFaults)
{
//call the 232 port method since there are not supposed to be any errors
return (pPort->Send(writeLength, transmitBuffer, pDebugStr));
}
m_pPort = pPort;
// new some data for the buffer before we corrupt it
pBuffer = (BYTE*)new char[writeLength+1]; //allocate 1 byte extra to allow for a "INSERT" corruption character
pBufferPtr = pBuffer;
bufferIndex = 0;
while (bufferIndex < writeLength)
{
// work out a random #, this must be done on a curve : W. Wahli AG, P. Christen
randN = rand();
faultPercent = (int)(randN*200/(float)RAND_MAX);
// IGNORE (only valid on the 1st byte of the message)
if ((0==bufferIndex)&&(faultPercent < m_errorFrequency)&&(m_ignoreReq))
{
ReportError("Ignore request");
break; // send 0 bytes out
}
if (faultPercent*8 < m_errorFrequency) // only corrupt about every 8th byte
{
// simulate a fault
randN = rand();
faultType = (int)(randN/(float)RAND_MAX*6); // fault types
chErr = (BYTE)(rand());
switch(faultType)
{
case 0:// INSERT
if (m_insertCharacters)
{
*pBufferPtr++ = chErr; // random character
*pBufferPtr++ = transmitBuffer[bufferIndex++];
ErrorDescription.Format("Inserted character x%02X", chErr);
ReportError(ErrorDescription);
}
break;
case 1:// DELETE
if (m_removeCharacters)
{
ErrorDescription.Format("Skipped character x%02X", transmitBuffer[bufferIndex]);
ReportError(ErrorDescription);
bufferIndex++; // do nothing, skips this byte
}
break;
case 2:// CORRUPT
if (m_modifyCharacters)
{
*pBufferPtr++ = chErr; // random character
bufferIndex++; //skip the character
ErrorDescription.Format("Corrupted to character x%02X", chErr);
ReportError(ErrorDescription);
}
break;
case 3:// MISSFRAME
if ((m_corruptFraming)&&((bufferIndex+1)!=writeLength))
{
*pBufferPtr++ = transmitBuffer[bufferIndex++];
// character added, now nuke the line.
NukePort();
ErrorDescription.Format("Generate framing error");
ReportError(ErrorDescription);
}
break;
case 4:// DELAY/SLOW
if (m_delaysPeriod)
{
len = (int)((LONG)pBufferPtr - (LONG)pBuffer);
if (len>0)
retValue = pPort->Send(len, pBuffer, pDebugStr);
//delay and then carry on
ErrorDescription.Format("Slow-down");
ReportError(ErrorDescription);
Sleep(m_delaysPeriod);
pBufferPtr = pBuffer;
*pBufferPtr++ = transmitBuffer[bufferIndex++];
}
break;
case 5:// PARITY
if ((m_parityFaults)&&((bufferIndex+1)!=writeLength))
{
*pBufferPtr++ = transmitBuffer[bufferIndex++];
// character added, now nuke the line.
NukePort();
ErrorDescription.Format("Generate parity error");
ReportError(ErrorDescription);
}
break;
}
// send the message thus far
//...
len = (int)((LONG)pBufferPtr - (LONG)pBuffer);
if (len)
retValue = pPort->Send(len, pBuffer, pDebugStr);
pBufferPtr = pBuffer; // reset our pointer to the beginning of the rest of this message
}
else
{
// append to the send buffer
*pBufferPtr++ = transmitBuffer[bufferIndex++];
// this way we do not have to TX each byte seperately
}
}
// un-nuke the port if it was
//...
UnNukePort();
// send the remaining bytes of the message normally.
len = (int)((LONG)pBufferPtr - (LONG)pBuffer);
if (len)
retValue = pPort->Send(len, pBuffer, pDebugStr);
else
retValue = FALSE;
// clean up
delete pBuffer;
return (retValue);
} // InjectErrors
// -------------------------------- ReportError --------------------------
void CRS232Noise::ReportError(LPCTSTR descr)
{
// inc error counter
m_errorsInjected++;
#ifdef _COMMS_DEBUGGING
OutputDebugString(descr);
OutputDebugString(".\r\n");
#endif
if (m_beep)
{
Beep(4000, 100);
}
} // ReportError
// ------------------------------- NukePort ---------------------------
// configure the port for a different baud so that it transmits garbage
//
BOOL CRS232Noise::NukePort()
{
BOOL error;
DCB dcb;
if (m_nukedPort)
return (TRUE);
error = GetCommState(m_pPort->h232Port,
&dcb);
// m_oldBaud = dcb.BaudRate;
// corrupt this one
switch (dcb.Parity)
{
case ODDPARITY:
dcb.Parity = EVENPARITY;
break;
case EVENPARITY:
dcb.Parity = ODDPARITY;
break;
case MARKPARITY:
dcb.Parity = SPACEPARITY;
break;
case SPACEPARITY:
dcb.Parity = MARKPARITY;
break;
default:
dcb.Parity = NOPARITY;
break;
}
SetCommState(m_pPort->h232Port, &dcb);
m_nukedPort = TRUE;
return (TRUE);
} // NukePort
// ------------------------------- NukeParity ---------------------------
// configure the port for a different baud so that it transmits garbage
//
BOOL CRS232Noise::NukeParity()
{
BOOL error;
DCB dcb;
if (m_nukedPort)
return (TRUE);
error = GetCommState(m_pPort->h232Port,
&dcb);
// m_oldBaud = dcb.BaudRate;
// corrupt this one
if (dcb.BaudRate > CBR_19200)
dcb.BaudRate = CBR_1200;
else
dcb.BaudRate = CBR_57600;
SetCommState(m_pPort->h232Port, &dcb);
m_nukedPort = TRUE;
return (TRUE);
} // NukeParity
// ----------------------------------- UnNukePort --------------------
BOOL CRS232Noise::UnNukePort()
{
DWORD error;
//DCB dcb;
if (m_nukedPort)
{
//restore the settings
//error = GetCommState(m_pPort->h232Port,
// &dcb);
//dcb.BaudRate = m_oldBaud;
//SetCommState(m_pPort->h232Port, &dcb);
m_pPort->ClosePort();
m_pPort->OpenPort(m_pPort->portNameS);
m_pPort->ReConfigurePort();
m_pPort->Purge();
ClearCommError(m_pPort->h232Port, &error, NULL);
#ifdef _COMMS_DEBUGGING
OutputDebugString("Port restored.\n");
#endif
}
m_nukedPort = FALSE;
return (TRUE);
} // UnNukePort
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -