www.pudn.com > mod_rssim6.zip > RS232Noise.cpp


// RS232Noise.cpp: implementation of the CRS232Noise class. 
// 
////////////////////////////////////////////////////////////////////// 
 
#include "stdafx.h" 
#include "mod_rssim.h" 
#include "RS232Noise.h" 
 
#ifdef _DEBUG 
#undef THIS_FILE 
static char THIS_FILE[]=__FILE__; 
#define new DEBUG_NEW 
#endif 
 
////////////////////////////////////////////////////////////////////// 
// Construction/Destruction 
////////////////////////////////////////////////////////////////////// 
 
CRS232Noise::CRS232Noise() 
{ 
   SetErrorTypes(0); // set for no errors 
   m_nukedPort = FALSE; 
   reserved = 0x5555AAAA; 
} 
 
CRS232Noise::~CRS232Noise() 
{ 
 
} 
 
// --------------------------------- SetErrorTypes ----------------------- 
void CRS232Noise::SetErrorTypes(LONG freq, 
                   LONG period, 
                   BOOL inserts ,  
                   BOOL removes ,  
                   BOOL misFrames , // off by default 
                   BOOL corrupts, 
                   BOOL ignore, 
                   BOOL beep 
                   ) 
{ 
   m_insertCharacters = inserts; 
   m_removeCharacters = removes; 
   m_corruptFraming   = misFrames; 
   m_modifyCharacters = corrupts; 
   m_errorFrequency   = freq; 
   m_ignoreReq        = ignore; 
   m_delaysPeriod     = period; 
   // 
   m_errorsInjected = 0; 
   m_beep = beep; 
} // SetErrorTypes 
 
// ------------------------------- GetErrorTypes ---------------------- 
void CRS232Noise::GetErrorTypes(int *freq, 
                               int *period,    // delays by (0=disable) 
                               BOOL *inserts,  
                               BOOL *removes,  
                               BOOL *misFrames, 
                               BOOL *corrupts, 
                               BOOL *ignore, 
                               BOOL *beep 
                               ) 
{ 
   *inserts =   m_insertCharacters;  
   *removes =   m_removeCharacters;  
   *misFrames = m_corruptFraming;    
   *corrupts =  m_modifyCharacters;  
   *freq =      m_errorFrequency;    
   *ignore =    m_ignoreReq;         
   *period =    m_delaysPeriod; 
   //                  
   *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 (0 == m_errorFrequency) 
   { 
      //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 # 
      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*5);  // 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; 
         } 
         // 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 
 
// ------------------------------- UnNukePort --------------------------- 
// 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 
   if (dcb.BaudRate > CBR_19200) 
      dcb.BaudRate = CBR_1200; 
   else 
      dcb.BaudRate = CBR_57600; 
    
   SetCommState(m_pPort->h232Port, &dcb); 
   m_nukedPort = TRUE; 
   return (TRUE); 
} // NukePort 
 
// ----------------------------------- 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