⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rs232noise.cpp

📁 mod_RSsim
💻 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 + -