bool BthPort::Connect() { int iResult; mSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM); if (mSocket == INVALID_SOCKET) { DWORD dwError = WSAGetLastError(); StartupStore(_T("... Bluetooth Port %u Unable to create socket, error=%lu%s"), GetPortIndex() + 1, dwError, NEWLINE); // 091117 return false; } SOCKADDR_BTH sa; memset(&sa, 0, sizeof (sa)); sa.addressFamily = AF_BTH; sa.serviceClassId = RFCOMM_PROTOCOL_UUID; sa.btAddr = StrToBTAddr(GetPortName()); iResult = connect(mSocket, (SOCKADDR*) & sa, sizeof (sa)); if (iResult == SOCKET_ERROR) { DWORD dwError = WSAGetLastError(); StartupStore(_T("... Bluetooth Port %u <%s> Unable connect, error=%lu%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117 return false; } StartupStore(_T(". Bluetooth Port %u Connect <%s> OK%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); return true; }
bool SerialPort::Close() { bool Ret = ComPort::Close(); // NOTICE: Ret is unused here, because Close is always returning true if (hPort != INVALID_HANDLE_VALUE) { // Close the communication port. #ifdef _DEBUG_STOP_RXTHREAD StartupStore(_T("... ComPort %d StopRxThread: Close Serial Port file handle !%s"), GetPortIndex() + 1, NEWLINE); #endif if (!CloseHandle(hPort)) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u close failed, error=%u%s"), GetPortIndex() + 1, dwError, NEWLINE); Ret = false; } else { #if (WINDOWSPC>0) || NEWCOMM // 091206 Sleep(2000); // needed for windows bug #endif #if !(WINDOWSPC>0) if (_PollingMode) Sleep(2000); #endif hPort = INVALID_HANDLE_VALUE; StartupStore(_T(". ComPort %u closed Ok.%s"), GetPortIndex() + 1, NEWLINE); // 100210 BUGFIX missing Ret = true; } } return Ret; }
bool GpsIdPort::Initialize() { _hLoc = ::CreateEvent(NULL, FALSE, FALSE, NULL); _hState = ::CreateEvent(NULL, FALSE, FALSE, NULL); _hGPS = ::GPSOpenDevice(_hLoc, _hState, NULL, 0); if (0 == _hGPS) { StartupStore(_T("Unable to Open GPS Intermediate driver %s"), NEWLINE); return false; } SetPortStatus(CPS_OPENOK); GPS_DEVICE dev = {0}; GPSResetData(dev); GPSGetDeviceState(&dev); StartupStore(_T("GPSID : DeviceState: %lX, ServiceState: %lX%s"), dev.dwDeviceState, dev.dwServiceState, NEWLINE); // StartupStore(_T("GPSID : LastDataTime: %s%s"), dev.ftLastDataReceived, NEWLINE); StartupStore(_T("GPSID : DrvPrefix; %s%s"), dev.szGPSDriverPrefix, NEWLINE); StartupStore(_T("GPSID : MxPrefix %s%s"), dev.szGPSMultiplexPrefix, NEWLINE); StartupStore(_T("GPSID : Name:%s%s"), dev.szGPSFriendlyName, NEWLINE); if (!StartRxThread()) { StartupStore(_T(". ComPort %u <%s> Failed to start Rx Thread%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); return false; } return true; }
void ComPort::ProcessChar(char c) { if (ComCheck_ActivePort>=0 && GetPortIndex()==(unsigned)ComCheck_ActivePort) { ComCheck_AddChar(c); } #ifdef RADIO_ACTIVE if(RadioPara.Enabled && devParseStream(devIdx, &c, 1, &GPS_INFO)) { // if this port is used for stream device, leave immediately. return; } #endif // RADIO_ACTIVE // last char need to be reserved for '\0' for avoid buffer overflow // in theory this should never happen because NMEA sentence can't have more than 82 char and _NmeaString size is 160. if (pLastNmea >= std::begin(_NmeaString) && (pLastNmea+1) < std::end(_NmeaString)) { if (c == '\n' || c == '\r') { // abcd\n , now closing the line also with \r *(pLastNmea++) = _T('\n'); *(pLastNmea) = _T('\0'); // terminate string. // process only meaningful sentences, avoid processing a single \n \r etc. if (std::distance(std::begin(_NmeaString), pLastNmea) > 5) { LockFlightData(); devParseNMEA(devIdx, _NmeaString, &GPS_INFO); UnlockFlightData(); } } else { *(pLastNmea++) = c; return; } } // overflow, so reset buffer pLastNmea = std::begin(_NmeaString); }
bool ComPort::Initialize() { if(!StartRxThread()) { StartupStore(_T(". ComPort %u <%s> Failed to start Rx Thread%s"), (unsigned)(GetPortIndex() + 1), GetPortName(), NEWLINE); return false; } return true; }
DWORD GpsIdPort::RxThread() { DWORD rc = 0; const int nh = 2; HANDLE handles[nh] = {0}; handles[0] = _hLoc; handles[1] = _hState; GPS_POSITION loc = {0}; GPSResetData(loc); GPS_DEVICE dev = {0}; GPSResetData(dev); bool listen = true; while (listen && !StopEvt.tryWait(0)) { DWORD dw = ::WaitForMultipleObjects(nh, handles, FALSE, 100); switch (dw) { case WAIT_OBJECT_0: rc = GPSGetPosition(_hGPS, &loc, 10000, 0); if(ERROR_SUCCESS == rc) { AddStatRx(1); NMEAParser::ParseGPS_POSITION(GetPortIndex(), loc, GPS_INFO); } GPSResetData(loc); break; case WAIT_OBJECT_0 + 1: rc = GPSGetDeviceState(&dev); if(ERROR_SUCCESS == rc) { AddStatRx(1); StartupStore(_T("GPSID : DeviceState: %lX, ServiceState: %lX%s"), dev.dwDeviceState, dev.dwServiceState, NEWLINE); } GPSResetData(dev); break; case WAIT_FAILED: listen = false; rc = ::GetLastError(); break; case WAIT_TIMEOUT: break; } } return rc; }
bool ComPort::StartRxThread() { StopEvt.reset(); // Create a read thread for reading data from the communication port. ReadThread.start(*this); ReadThread.setPriority(Poco::Thread::PRIO_NORMAL); //THREAD_PRIORITY_ABOVE_NORMAL if(!ReadThread.isRunning()) { // Could not create the read thread. StartupStore(_T(". ComPort %u <%s> Failed to start Rx Thread%s"), (unsigned)(GetPortIndex() + 1), GetPortName(), NEWLINE); // LKTOKEN _@M761_ = "Unable to Start RX Thread on Port" StatusMessage(mbOk, TEXT("Error"), TEXT("%s %s"), MsgToken(761), GetPortName()); //DWORD dwError = GetLastError(); return false; } return true; }
DWORD SerialPort::RxThread() { #if ( (WINDOWSPC == 0)) && !NEWCOMM // 100222 DWORD dwCommModemStatus = 0; // Specify a set of events to be monitored for the port. #endif DWORD dwBytesTransferred = 0; // 091117 initialized variables _Buff_t szString; FILETIME CreationTime, ExitTime, StartKernelTime, EndKernelTime, StartUserTime, EndUserTime; Purge(); #if TRACETHREAD StartupStore(_T("############## PORT=%d threadid=%d\n"), GetPortIndex(), GetCurrentThreadId()); if (GetPortIndex() = 0) _THREADID_PORT1 = GetCurrentThreadId(); if (GetPortIndex() = 1) _THREADID_PORT2 = GetCurrentThreadId(); if (GetPortIndex() != 1 && GetPortIndex() != 2) _THREADID_UNKNOWNPORT = GetCurrentThreadId(); #endif // Specify a set of events to be monitored for the port. _dwMask = EV_RXFLAG | EV_CTS | EV_DSR | EV_RING | EV_RXCHAR; #if ( (WINDOWSPC == 0)) && !NEWCOMM SetCommMask(hPort, _dwMask); #endif #if (WINDOWSPC<1) if (!_PollingMode) SetCommMask(hPort, _dwMask); #endif while ((hPort != INVALID_HANDLE_VALUE) && (::WaitForSingleObject(hStop, 0) == WAIT_TIMEOUT)) { GetThreadTimes(hReadThread, &CreationTime, &ExitTime, &StartKernelTime, &StartUserTime); UpdateStatus(); #if (WINDOWSPC>0) || NEWCOMM // 091206 // PC version does BUSY WAIT Sleep(50); // ToDo rewrite the whole driver to use overlaped IO on W2K or higher #else if (_PollingMode) Sleep(100); else // Wait for an event to occur for the port. if (!WaitCommEvent(hPort, &dwCommModemStatus, 0)) { // error reading from port Sleep(100); } #endif // Re-specify the set of events to be monitored for the port. // SetCommMask(hPort, dwMask1); // #if (WINDOWSPC == 0) 091206 #if ( (WINDOWSPC == 0)) && !NEWCOMM if (_PollingMode || (dwCommModemStatus & EV_RXFLAG) || (dwCommModemStatus & EV_RXCHAR)) // Do this only for non-PC #endif { // Loop for waiting for the data. do { // Read the data from the serial port. dwBytesTransferred = ReadData(szString); if (dwBytesTransferred > 0) { if (ProgramStarted >= psNormalOp) { // ignore everything until started std::for_each(begin(szString), begin(szString) + dwBytesTransferred, std::bind1st(std::mem_fun(&SerialPort::ProcessChar), this)); } } else { dwBytesTransferred = 0; } Sleep(50); // JMW20070515: give port some time to // fill... prevents ReadFile from causing the // thread to take up too much CPU if ((GetThreadTimes(hReadThread, &CreationTime, &ExitTime, &EndKernelTime, &EndUserTime)) == 0) { if (GetPortIndex() == 0) Cpu_PortA = 9999; else Cpu_PortB = 9999; } else { Cpustats((GetPortIndex() == 0) ? &Cpu_PortA : &Cpu_PortB, &StartKernelTime, &EndKernelTime, &StartUserTime, &EndUserTime); } if (::WaitForSingleObject(hStop, 0) != WAIT_TIMEOUT) { dwBytesTransferred = 0; } } while (dwBytesTransferred != 0); } // give port some time to fill Sleep(5); // Retrieve modem control-register values. #if ((WINDOWSPC == 0)) if (!_PollingMode) { // this is causing problems on PC BT, apparently. Setting Polling will not call this, but it is a bug GetCommModemStatus(hPort, &dwCommModemStatus); } #endif } DirtyPurge(); return 0; }
bool SerialPort::Initialize() { TCHAR sysPortName[20]; DCB PortDCB; #if (WINDOWSPC>0) // Do not use COMn , use \\.\COMnn on PC version _stprintf(sysPortName, _T("\\\\.\\%s"), GetPortName()); #else // Do not use COMn , use COMn: on WinCE version _stprintf(sysPortName, _T("%s:"), GetPortName()); #endif StartupStore(_T(". ComPort %u Initialize <%s> speed=%u bit=%u %s"),GetPortIndex()+1,GetPortName(),_dwPortSpeed,8-_dwPortBit,NEWLINE); hPort = CreateFile(sysPortName, // Pointer to the name of the port GENERIC_READ | GENERIC_WRITE, // Access (read-write) mode 0, // Share mode NULL, // Pointer to the security attribute OPEN_EXISTING, // How to open the serial port FILE_ATTRIBUTE_NORMAL, // Port attributes NULL); // Handle to port with attribute // to copy if (hPort == INVALID_HANDLE_VALUE) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init failed, error=%u%s"), GetPortIndex() + 1, dwError, NEWLINE); // 091117 StatusMessage(MB_OK, NULL, TEXT("%s %s"), gettext(TEXT("_@M762_")), GetPortName()); goto failed; } StartupStore(_T(". ComPort %u <%s> is now open%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); PortDCB.DCBlength = sizeof (DCB); // Get the default port setting information. if (GetCommState(hPort, &PortDCB)==0) { StartupStore(_T("... ComPort %u GetCommState failed, error=%u%s"),GetPortIndex()+1,GetLastError(),NEWLINE); // @M759 = Unable to Change Settings on Port StatusMessage(MB_OK|MB_ICONINFORMATION, NULL, TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName()); goto failed; } // Change the DCB structure settings. PortDCB.BaudRate = _dwPortSpeed; // Current baud PortDCB.fBinary = TRUE; // Binary mode; no EOF check PortDCB.fParity = TRUE; // Enable parity checking PortDCB.fOutxCtsFlow = FALSE; // CTS output flow control: when TRUE, and CTS off, output suspended PortDCB.fOutxDsrFlow = FALSE; // DSR output flow control PortDCB.fDtrControl = DTR_CONTROL_ENABLE; PortDCB.fDsrSensitivity = FALSE; // DSR sensitivity PortDCB.fTXContinueOnXoff = TRUE; // XOFF continues Tx PortDCB.fOutX = FALSE; // No XON/XOFF out flow control PortDCB.fInX = FALSE; // No XON/XOFF in flow control PortDCB.fErrorChar = FALSE; // Disable error replacement PortDCB.fNull = FALSE; // Disable null removal PortDCB.fRtsControl = RTS_CONTROL_ENABLE; // RTS flow control PortDCB.fAbortOnError = FALSE; switch (_dwPortBit) { case bit7E1: PortDCB.ByteSize = 7; PortDCB.Parity = EVENPARITY; break; case bit8N1: default: PortDCB.ByteSize = 8; PortDCB.Parity = NOPARITY; break; } PortDCB.StopBits = ONESTOPBIT; PortDCB.EvtChar = '\n'; // wait for end of line, RXFLAG should detect it if (!SetCommState(hPort, &PortDCB)) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init <%s> change setting FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117 // @M759 = Unable to Change Settings on Port StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M759_")), GetPortName()); goto failed; } if (SetRxTimeout(RXTIMEOUT) == -1) { DWORD dwError = GetLastError(); StartupStore(_T("... ComPort %u Init <%s> change TimeOut FAILED, error=%u%s"), GetPortIndex() + 1, GetPortName(), dwError, NEWLINE); // 091117 // LKTOKEN _@M760_ = "Unable to Set Serial Port Timers" StatusMessage(MB_OK, TEXT("Error"), TEXT("%s %s"), gettext(TEXT("_@M760_")), GetPortName()); goto failed; } SetupComm(hPort, 1024, 1024); // Direct the port to perform extended functions SETDTR and SETRTS // SETDTR: Sends the DTR (data-terminal-ready) signal. // SETRTS: Sends the RTS (request-to-send) signal. EscapeCommFunction(hPort, SETDTR); EscapeCommFunction(hPort, SETRTS); if(!ComPort::Initialize()) { // no need to log failed of StartRxThread it's already made in ComPort::Initialize(); goto failed; } StartupStore(_T(". ComPort %u Init <%s> end OK%s"), GetPortIndex() + 1, GetPortName(), NEWLINE); return true; failed: if(hPort != INVALID_HANDLE_VALUE) { if (!CloseHandle(hPort)) { StartupStore(_T("... ComPort %u Init <%s> close failed, error=%u%s"),GetPortIndex() + 1, GetPortName(),NEWLINE); } else { StartupStore(_T("... ComPort %u Init <%s> closed%s"),GetPortIndex() + 1, GetPortName(),NEWLINE); } hPort = INVALID_HANDLE_VALUE; #if (WINDOWSPC>0) || NEWCOMM // 091206 Sleep(2000); // needed for windows bug #endif #if !(WINDOWSPC>0) if (_PollingMode) Sleep(2000); #endif } return false; }
bool ComPort::StopRxThread() { StopEvt.set(); #ifdef _DEBUG_STOP_RXTHREAD StartupStore(_T("... ComPort %u StopRxThread: Cancel Wait Event !%s"), (unsigned)(GetPortIndex() + 1), NEWLINE); #endif CancelWaitEvent(); #ifdef _DEBUG_STOP_RXTHREAD StartupStore(_T("... ComPort %u StopRxThread: Wait End of thread !%s"), (unsigned)(GetPortIndex() + 1), NEWLINE); #endif if (ReadThread.isRunning()) { if(!ReadThread.tryJoin(20000)) { StartupStore(_T("... ComPort %u StopRxThread: RX Thread forced to terminate!%s"), (unsigned)(GetPortIndex() + 1), NEWLINE); // TODO : Kill Thread ?? } } StopEvt.reset(); return true; }
void ComPort::SetPortStatus(int nStatus) { if (GetPortIndex() < NUMDEV) { ComPortStatus[GetPortIndex()] = nStatus; } }
void ComPort::AddStatErrTx(unsigned dwBytes) { if (GetPortIndex() < NUMDEV) { ComPortErrTx[GetPortIndex()] += dwBytes; } }
void ComPort::AddStatRx(unsigned dwBytes) { if (GetPortIndex() < NUMDEV) ComPortRx[GetPortIndex()] += dwBytes; }
void ComPort::run() { StartupStore(_T(". ComPort %u ReadThread : started%s"), (unsigned)(GetPortIndex() + 1), NEWLINE); RxThread(); StartupStore(_T(". ComPort %u ReadThread : terminated%s"), (unsigned)(GetPortIndex() + 1), NEWLINE); }