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;