testcam

DWORD ovlRes;
	DWORD dwMask, dwRet;
	ECHOSTATUS ret;	
	unsigned char senddata[20];	// size of senddata
	int csidx = msgSize+3;		// checksum index
	int sendlen = msgSize+4;	// length of senddata
 
	if(!m_hcom)					// validation of com handle
		return TRANSFAIL;
 
	memset(senddata, 0, sizeof(senddata));	// clear memory
	senddata[0] = STX;						// starting byte
	senddata[1] = msgSize;					// LSB size
	senddata[2] = 0x00;						// MSB size
	senddata[3] = cmdcode;					// command byte
 
	for(int i = 3; i < 3+msgSize; i++)	{
		senddata[i] = msg[i-3];				// copy data from msg byte to senddata
		senddata[csidx] += msg[i-3];		// acculumate message bytes to get checksum
	}
 
	// take 2's complement for checksum
	senddata[csidx] = ~senddata[csidx];	
	senddata[csidx]++;
 
 
	bool bDone = false;
 
	while(!bDone)	
	{		
		OVERLAPPED ovl = {0};
		ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 
		// **********************************************************************
		// send data to camera
		// overlapped I/O
		// CreateFile is in use of  FILE_FLAG_OVERLAPPED 
		// If WriteFile is pending then wait till it is done.
		// We wait for 500ms in maximum.
		// When it is time over, it simply returns TRANSFAIL.
		//***********************************************************************
		if(!WriteFile(m_hcom, senddata, sendlen, &dwRet, &ovl))		{
			// There is an error reported while writing
			if(GetLastError() != ERROR_IO_PENDING)	{
				CloseHandle(ovl.hEvent);
				return TRANSFAIL;
			}
			else	{		// writing is pending
				switch(WaitForSingleObject(ovl.hEvent, WRITE_CHK_TIMEOUT))
				{
					case WAIT_OBJECT_0 :	// got signaled
						if (!GetOverlappedResult(m_hcom, &ovl, &ovlRes, FALSE))	{
							CloseHandle(ovl.hEvent);
							return TRANSFAIL;
						}
						break;
					default:
						CloseHandle(ovl.hEvent);
						return TRANSFAIL;
				}
			}
		}
		//***********************************************************************
 
		// set event to non-signaled
		ResetEvent(ovl.hEvent);
 
		// **********************************************************************
		// wait for receiving character from camera
		// overlapped I/O
		// CreateFile is in use of  FILE_FLAG_OVERLAPPED 
		// We wait for 500ms in maximum.
		// When it is time over, it simply returns TRANSFAIL.
		//***********************************************************************
 
		dwMask = EV_RXCHAR;
		SetCommMask(m_hcom, dwMask);			
		if(!WaitCommEvent(m_hcom, &dwMask, &ovl))	{
			// There is an error reported while waiting comm event
			if(GetLastError() != ERROR_IO_PENDING)	
				return TRANSFAIL;
			else	{	// wating comm event is pending				
				switch(WaitForSingleObject(ovl.hEvent, STATUS_CHK_TIMEOUT))
				{
					case WAIT_OBJECT_0 :
						if (!GetOverlappedResult(m_hcom, &ovl, &ovlRes, FALSE)){
							CloseHandle(ovl.hEvent);
							return TRANSFAIL;
						}
						break;
					case WAIT_TIMEOUT :						
						CloseHandle(ovl.hEvent);
						return TIMEOUT;
					default:
						CloseHandle(ovl.hEvent);
						return EVENTERROR;
				}
			}
		}
		//***********************************************************************
 
		// set event to non-signaled
		ResetEvent(ovl.hEvent);
 
 
		// **********************************************************************
		// read data from camera when there is incoming data
		// overlapped I/O
		// CreateFile is in use of  FILE_FLAG_OVERLAPPED 
		// We wait for 500ms in maximum.
		// When it is time over, it simply returns TRANSFAIL.
		//***********************************************************************
 
		// This delay is necessary to prevent MS4100 crashed
		// This is a hardware characteristic.
		//Sleep(30);
 
		if(dwMask & EV_RXCHAR)	{
			memset(echo, 0, echoSize);
			if(!ReadFile(m_hcom, echo, echoSize, &dwRet, &ovl))	{
				// There is an error reported while writing
				if(GetLastError() != ERROR_IO_PENDING)	{
					CloseHandle(ovl.hEvent);
					return TRANSFAIL;
				}
				else	{		// readng is pending
					switch(WaitForSingleObject(ovl.hEvent, READ_CHK_TIMEOUT))
					{
						case WAIT_OBJECT_0 :	// got signaled					
							if (!GetOverlappedResult(m_hcom, &ovl, &ovlRes, FALSE))	{
								CloseHandle(ovl.hEvent);
								return TRANSFAIL;
							}
							break;
						case WAIT_TIMEOUT :
							CloseHandle(ovl.hEvent);
							return TIMEOUT;
						default:
							CloseHandle(ovl.hEvent);
							return TRANSFAIL;
					}
				}
			}
		}
		//***********************************************************************
 
		// set event to non-signaled
		ResetEvent(ovl.hEvent);
 
		// **********************************************************************
		// take a look into checksum byte to see if checksum error occurs.
		// **********************************************************************
		unsigned char retcs = 0;
		for(int i = 3; i < echoSize-1; i++)
			retcs += (unsigned char)echo[i];
		retcs = (unsigned char)~retcs;
		retcs++;
 
		switch(atoi((char*)&echo[echoSize-2]))
		{
			case 0:
				ret= CMDCOMPLETE;
				OutputDebugString("CMDCOMPLETE\n");
				bDone = true;
				break;
			case 1:
				ret = CMDFAIL;
				OutputDebugString("CMDFAIL\n");
				bDone = false;
				break;
			case 2:
				ret = CHECKSUMFAIL;
				OutputDebugString("CHECKSUMFAIL\n");
				bDone = false;
				break;
			case 3:
				ret = UNRECOGNIZEDCMD;
				OutputDebugString("UNRECOGNIZEDCMD\n");
				bDone = true;
				break;
		}
 
		// **********************************************************************
		// Error reported.
		// Clear the comm error.
		// **********************************************************************
		if(!bDone)	{			
			DWORD   dwErrorMask;
			COMSTAT comstat;
			ClearCommError(m_hcom,&dwErrorMask,&comstat); 
			bDone = false;
 
			if(dwErrorMask == 0)
			{
				memset(echo, 0, echoSize);
				if(!ReadFile(m_hcom, echo, comstat.cbInQue, &dwRet, &ovl))	{
					// There is an error reported while writing
					if(GetLastError() != ERROR_IO_PENDING)	{
						CloseHandle(ovl.hEvent);
						return TRANSFAIL;
					}
					else	{		// readng is pending
						// set event to non-signaled
						ResetEvent(ovl.hEvent);
						switch(WaitForSingleObject(ovl.hEvent, 2000))
						{
							case WAIT_OBJECT_0 :	// got signaled					
								if (!GetOverlappedResult(m_hcom, &ovl, &ovlRes, FALSE))	{
									CloseHandle(ovl.hEvent);
									return TRANSFAIL;
								}
								break;
							case WAIT_TIMEOUT :
								CloseHandle(ovl.hEvent);
								return TIMEOUT;
							default:
								CloseHandle(ovl.hEvent);
								return TRANSFAIL;
						}
					}		
				}				
			}
		}	
 
		//***********************************************************************
 
		// Close event handle
		if(ovl.hEvent)
			CloseHandle(ovl.hEvent);
	}	
 
	return ret;