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))
		{	// Wenn noch nicht alle Bytes empfangen wurden und es noch kein Timeout gab, wird auf weiteres ReceiveEvent gewartet

			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();
		}
	}

	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;
}