short CCP4002Prot::Transmit(unsigned int cpStatus)
{
	short transRet = 0;     // Rckgabewert von Trans()
   short recvRet  = 0;     // Rckgabewert von Recv()

   m_cpStatus = cpStatus;
   switch (m_cpStatus)
   {
   case CP_A_SEND:   m_transChar = 'A';  m_bytesSollRecv = 0;     m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                               break; // Reset CP4002
   case CP_J_SEND:   m_transChar = 'J';  m_bytesSollRecv = 16;    m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                               break; // GC-Ident anfordern
   case CP_N_SEND:   m_transChar = 'N';  m_bytesSollRecv = 0;     m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                               break; // FlushMode prfen?
   case CP_C_SEND:   m_transChar = 'C';  m_bytesSollRecv = 14;    m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                               break; // SBlockA
   case CP_H_SEND:   m_transChar = 'H';  m_bytesSollRecv = 14;    m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                               break; // SBlockB
   case CP_SMB_SEND: m_transChar = '\0'; m_bytesSollRecv = 0;     m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                             break; // a-m Parameter
   case CP_D_SEND:   m_transChar = 'D';  m_bytesSollRecv = 29;    m_recvTimeoutSec = CP_NORMAL_TIMEOUT;                                                             break; // Methode
   case CP_START:    m_transChar = 'B';  m_bytesSollRecv = 42000; m_recvTimeoutSec = ((SMethodBlock.sample_time*1000) + 5000); break; // Analysendaten             
   default:          ASSERT(false);                                                                                                                                                                                                              break; // Sollte nie vorkommen!             
   }

   memset(m_transBuf, 0x00, CP_TRANSMIT_MAX_LEN);

   switch (m_cpStatus)
   {
   case CP_A_SEND:
   case CP_J_SEND:
   case CP_N_SEND:
   case CP_C_SEND:
   case CP_H_SEND:
   case CP_D_SEND:
   case CP_START: 
		// Befehlszeichen senden
      m_transBuf[0] = m_transChar;
      m_transBuflen = 1;

      transRet = Trans();
      if (0 == transRet)	// Wenn das Senden erfolgreich war, wird empfangen
			recvRet = Recv();
      break;
      
   case CP_SMB_SEND:
		// Parameter a-m senden
      m_pSMethodBlock = (char *)&SMethodBlock;
      m_transBuflen = 2;

      for (int cSmb = 'a'; cSmb <= 'm'; cSmb++)
      {
			if (cSmb == 's')		// 19tes Element aus SMB berspringen
				cSmb++;
                              
         m_transBuf[0] = cSmb;
         m_transBuf[1] = *m_pSMethodBlock++;
         
         transRet = Trans();     
         if (0 == transRet)	// Wenn das Senden erfolgreich war, wird empfangen
				recvRet = Recv();
      }
      break;

   default:	// Sollte nie vorkommen!
		ASSERT(false);
		break;
   }

   return (transRet | recvRet);
}

short CCP4002Prot::Trans(void)
{
	short ret    = 0;
   DWORD retErr = 0;

   SetCpStatusString(TRANSMIT);

   if (false == WriteCanQueue(m_comnum, m_transBuf, m_transBuflen))
   {       
		DTLOG(m_logid, DT_CP4002PROT_CAN_WRITE_FAILED);
      retErr = GetLastError();
      m_errCounterTrans++;
      ret = -1;
   }
   else
   {
      retErr = 0;
      m_errCounterTrans = 0;
      ret = 0;
   }

   return ret;
}

short CCP4002Prot::Recv(void)
{	// Wartet auf ReceiveEvents und berwacht Timeouts
	DWORD waitResult = 0;
	short ret        = 0;   
  
	SetCpStatusString(RECEIVE);

	m_bytesReceived  = 0;
	m_recvTimeout    = false;

   memset(m_recvBuf, 0x00, CP_RECEIVE_MAX_LEN);                                   

   bool timeout = false;
   
   if (m_bytesSollRecv > 0)
   {	 // Wenn gesendeter Befehl eine Antwort erwartet, wird auf ReceiveEvent gewartet
		if (CP_START == m_cpStatus)
      {
			m_CountSampleTime = true;
			m_startSampleTime = time(NULL);
      }

      waitResult = WaitForSingleObject(m_recvEvent, m_recvTimeoutSec);
      switch (waitResult)
      {
      case WAIT_OBJECT_0:     
			break;
      case WAIT_TIMEOUT:
			timeout = true;
         ret = -11;
         break;
		}
      ResetEvent(m_recvEvent);

      while ((m_bytesReceived < m_bytesSollRecv) && (!timeout) && (m_ProtocollIsRunning))
      {	// Wenn noch nicht alle Bytes empfangen wurden und es noch kein Timeout gab, wird auf weiteres ReceiveEvent gewartet
			// Prfung von 'm_ProtocollIsRunning' ermglicht sofortiges Beenden whrend Datenempfang von Messwerk
         if (CP_START == m_cpStatus && false == m_CountRunTime)
         {	// Nach dem Splen wird die RunTime gezhlt und die Ventile geschaltet
            m_CountRunTime = true;
            m_startRunTime = time(NULL);

            m_flushingFinished = true;     
         }

         waitResult = WaitForSingleObject(m_recvEvent, CP_ANADATA_TIMEOUT_2);
         switch (waitResult)
         {
         case WAIT_OBJECT_0:
				break;
         case WAIT_TIMEOUT:
            timeout = true;
            ret = -12;
            break;
         }
         ResetEvent(m_recvEvent);
		}
   }

   if (m_bytesSollRecv > 0)
   {
		if ((!timeout) && m_bytesReceived == m_bytesSollRecv)
      {
			ret = ProcessRecvData();
         xValue(CP4002ReqWithAnsw)++;
         //SaveXVars();
      }
      else
      {
         DTLOG(m_logid, DT_CP4002PROT_RECEIVE_FAILED, m_bytesSollRecv, m_bytesReceived);
         TRACE(_T("NOT all Bytes received or timeout! %i\n"), m_bytesReceived); 
         //TRACE(_T("m_recvBuf: %S\n"), m_recvBuf);
         xValue(CP4002ReqWithoutAnsw)++;
         //SaveXVars();
			Sleep(500);
      }
   }

	if (CP_START == m_cpStatus)
   {
		m_CountSampleTime = false;
		m_CountRunTime    = false;
   }

   return ret;
}

bool CCP4002Prot::RecvFomCAN(CANMSG *cm)
{	// Hier kommt Empfangenes von CAN an
   CANMSG *cmTemp = cm;
   
   memcpy((m_recvBuf+m_bytesReceived), cmTemp->byContent, cmTemp->byDatalength);

   if (0 == m_bytesReceived)       
		m_bytesReceivedAll = 0;
   m_bytesReceivedAll += cmTemp->byDatalength;

   if (CP_START == m_cpStatus)
		SetCpStatusString(RECEIVE);

   m_bytesReceived += cmTemp->byDatalength;

   if (cmTemp->byDatalength > 0)
		SetEvent(m_recvEvent);  // Dem Protokoll melden, dass neue Daten eingegangen sind

   return true;
}