void CCallHistoryDlg::OnButtonReply() { int nCurSel; if(m_pHistData->IsEmpty(m_DispFilter)) return; else if((nCurSel = m_lstHist.GetNextItem(-1, LVNI_SELECTED)) == -1) { AfxMessageBox(IDS_NOITEMSEL, MB_OK | MB_ICONINFORMATION); return; } CString strUnknown; strUnknown.LoadString(IDS_UNKNOWN); CSerialPort* pComm = ((CHSDPAApp*)AfxGetApp())->m_pSerialPort; ASSERT(pComm); if(pComm->CommIsReady()) { WORD nIndex = m_DspIndexArr[m_DispFilter][nCurSel]; ASSERT(nIndex < m_pHistData->GetCount(m_DispFilter)); WPARAM wParam = 0; LPARAM lParam = (LPARAM)(LPCTSTR)(m_pHistData->GetItem(m_DispFilter, nIndex)).szNumber; if(wcslen((LPCTSTR)lParam) > 0 && wcscmp((LPCTSTR)lParam, strUnknown)) { ::SendMessage(GetOwner()->GetSafeHwnd(),IDT_CALL_DIAL, wParam, lParam); OnOK(); } else AfxMessageBox(IDS_SELCONNECT_NULLNUM); } }
BOOL CSetupCallDlg::AtSndSetPrivacy(int nPrivacy) { CHSDPADlg *pMainDlg = NULL; pMainDlg = (CHSDPADlg*)AfxGetMainWnd(); char szAtBuf[20] = {0}; if (pMainDlg && pMainDlg->m_pCallDlg->m_blIsInCalling) { const char szATSetPower[]="AT+CPRIV="; sprintf(szAtBuf, "%s%d\r", szATSetPower, nPrivacy); } else { const char szATSetPower[]="AT$HVPRIV="; sprintf(szAtBuf, "%s%d\r", szATSetPower, nPrivacy); } CSerialPort* pComm = ((CHSDPAApp*)AfxGetApp())->m_pSerialPort; ASSERT(pComm); if(pComm->WriteToPort(szAtBuf, strlen(szAtBuf))) { RegisterAtRespFunc(ATRESP_GENERAL_AT, AtRespSetPrivacy, (LPVOID)this); if(WAIT_OBJECT_0 == WaitForSingleObject(m_hCallSetupEvt, SYNCINIT_TIMEOUT_SHORT)) return TRUE; } return FALSE; }
UINT WINAPI CSerialPort::ListenThread( void* pParam ) { /** 得到本类的指针 */ CSerialPort *pSerialPort = reinterpret_cast<CSerialPort*>(pParam); // 线程循环,轮询方式读取串口数据 while (!pSerialPort->s_bExit) { UINT BytesInQue = pSerialPort->GetBytesInCOM(); /** 如果串口输入缓冲区中无数据,则休息一会再查询 */ if ( BytesInQue == 0 ) { Sleep(SLEEP_TIME_INTERVAL); continue; } /** 读取输入缓冲区中的数据并输出显示 */ char cRecved = 0x00; do { cRecved = 0x00; if(pSerialPort->ReadChar(cRecved) == true) { std::cout << cRecved ; continue; } }while(--BytesInQue); } return 0; }
//---------------------------------------------------------------------------- BOOL CDialogOption::OnInitDialog() { //---------------------------------------------------------------------------- CDialog::OnInitDialog(); // Entrypoint to change the language // ...make a class for language translation (see DigitalSimulator/ResourceTranslator // SetWindowText("conrad-elektronik card 967720 parameter"); GetDlgItem(IDC_GERAETENUMMER)->SetWindowText("Device id"); GetDlgItem(IDC_COM_PORT)->SetWindowText("COM:"); GetDlgItem(IDC_NO_PORT_AVAILABLE)->SetWindowText("- no free seriel port available -"); GetDlgItem(IDOK)->SetWindowText("Ok"); GetDlgItem(IDCANCEL)->SetWindowText("Cancel"); // int ownPort = m_portNr; CSerialPort port; CString portID; int selection=0; for(int i=1;i<5;i++){ if(port.Init(i)){ // Falls der eigene Port in der Liste vorkommt brauch ich diesen // spaeter nicht noch einmal eintragen // if(ownPort==i){ ownPort=-1; selection = i-1; } // gueltigen Port eintragen // portID.Format("%d",i); m_portCombo.AddString(portID); } } // eigenen Port als eine gueltige Auswahl eintragen // if(ownPort != -1){ portID.Format("%d",ownPort); m_portCombo.AddString(portID); } if(m_portCombo.GetCount()){ m_portCombo.SetCurSel(selection); m_noPortStatic.ShowWindow(FALSE); } else{ m_portCombo.EnableWindow(FALSE); m_geraeteIDEdit.EnableWindow(FALSE); m_noPortStatic.ShowWindow(TRUE); } return TRUE; // return TRUE unless you set the focus to a control // EXCEPTION: OCX-Eigenschaftenseiten sollten FALSE zurückgeben }
int main() { try { CSerialPort *serPort; string serName; cout << "Serial port test application: Use it with a loopback serial port (pins 2-3 connected)"<< endl; cout << "Enter the serial port name (e.g. COM1, ttyS0, ttyUSB0): "; getline(cin,serName); cout << endl; cout << "Opening serial port..."; serPort = new CSerialPort(serName); cout << "OK" << endl; cout << "Setting timeouts..."; serPort->setTimeouts(100,1,100, 1, 100); cout << "OK" << endl; cout << "Setting baud rate..."; serPort->setConfig(500000); cout << "OK" << endl; for (int i=0;i<10;i++) { // Test write: cout << "Writing test data..."; const char buf1[] = "Hello world!"; size_t written = serPort->Write(buf1,sizeof(buf1)); cout << written << " bytes written." << endl; // Read: cout << "Reading data..."; char buf2[100]; size_t nRead = serPort->Read(buf2,sizeof(buf2)); cout << nRead << " bytes read: '"; buf2[nRead]=0; cout << buf2 << "'" << endl; } delete serPort; } catch(std::exception &e) { cerr << e.what() << endl; return -1; } return 0; }
EXPORT_C TBool CloseSerialPort(SerialPort aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); TBool returnVal = pPort->Close(); delete pPort; return (returnVal); }
EXPORT_C TBool ReceiveBufferLength(SerialPort aPort, TInt & aSize) { TBool ok = EFalse; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); ok = pPort->ReceiveBufferLength(aSize); } return (ok); }
EXPORT_C TBool GetPortConfig (SerialPort aPort, TCommConfig & config) { TBool ok = EFalse; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); ok = pPort->GetPortConfig(config); } return (ok); }
EXPORT_C TBool WriteCancel(SerialPort aPort) { TBool ok = EFalse; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); ok = pPort->WriteCancel(); } return (ok); }
EXPORT_C TInt SetConfig(SerialPort aPort, const TCommConfig & aRequiredConfig ) { TInt error = KErrUnknown; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); error = pPort->SetConfig(aRequiredConfig); } return error; }
void CSerialPort::_OnCompletion(DWORD dwErrorCode, DWORD dwCount, LPOVERLAPPED lpOverlapped) { //Validate our parameters ASSERT(lpOverlapped); //Convert back to the C++ world CSerialPort* pSerialPort = (CSerialPort*) lpOverlapped->hEvent; ASSERT(pSerialPort->IsKindOf(RUNTIME_CLASS(CSerialPort))); //Call the C++ function pSerialPort->OnCompletion(dwErrorCode, dwCount, lpOverlapped); }
EXPORT_C TAny * OpenSerialPortL(SerialServer aServer, TUint aPort) { CSerialServer * pServer = static_cast<CSerialServer *>(aServer); CSerialPort * pPort = new(ELeave) CSerialPort; if (pPort->Open(*pServer, aPort) == EFalse) { delete pPort; pPort = NULL; } return (static_cast<TAny *>(pPort)); }
BOOL CSetupCallDlg::AtSndPrivacy() { char szAtBuf[20] = {0}; strcpy(szAtBuf, "AT$HVPRIV?\r"); CSerialPort* pComm = ((CHSDPAApp*)AfxGetApp())->m_pSerialPort; ASSERT(pComm); if(pComm->WriteToPort(szAtBuf, strlen(szAtBuf))) { RegisterAtRespFunc(ATRESP_GENERAL_AT, AtRespPrivacy, (LPVOID)this); if(WAIT_OBJECT_0 == WaitForSingleObject(m_hCallSetupEvt, SYNCINIT_TIMEOUT_SHORT)) return TRUE; } return FALSE; }
EXPORT_C TBool Write(SerialPort aPort, TRequestStatus & aStatus, TTimeIntervalMicroSeconds32 aTimeout, const TDesC8 &aDes, TInt aLength) { TBool ok = EFalse; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); ok = pPort->Write(aStatus, aTimeout, aDes, aLength); } return (ok); }
EXPORT_C TBool Read(SerialPort aPort, TRequestStatus & aStatus, TTimeIntervalMicroSeconds32 aTimeout, TDes8 &aDes, TInt aLength) { TBool ok = EFalse; if (aPort) { CSerialPort * pPort = static_cast<CSerialPort *>(aPort); ok = pPort->Read(aStatus, aTimeout, aDes, aLength); } return ok; }
void loop() { serial.process(); io.process(); // The following is for transmitting if (m_dstarEnable && m_modemState == STATE_DSTAR) dstarTX.process(); if (m_dmrEnable && m_modemState == STATE_DMR) { if (m_duplex) dmrTX.process(); else dmrDMOTX.process(); } if (m_ysfEnable && m_modemState == STATE_YSF) ysfTX.process(); if (m_p25Enable && m_modemState == STATE_P25) p25TX.process(); if (m_modemState == STATE_DSTARCAL) calDStarTX.process(); if (m_modemState == STATE_DMRCAL) calDMR.process(); if (m_modemState == STATE_IDLE) cwIdTX.process(); }
void signal_handler_IO(int _status) { static uint8_t buffer[PIPE_BUF]; int buffersize, fd_sp; static std::vector<uint8_t> vctBuffer; switch (_status) { case SIGIO: // READ memset(buffer, 0, PIPE_BUF); buffersize = 0; fd_sp = SerialPort.GetFileDescriptor(); if( (buffersize = read(fd_sp,buffer,PIPE_BUF))==0) { break; } try{ for(int k=0;k<buffersize;k++) { if( (buffer[k] == 0x7E) && !vctBuffer.empty() ) { SerialPort.addDataVector(vctBuffer); vctBuffer.clear(); } vctBuffer.push_back(buffer[k]); } }catch(CSerialPort::SerialPortRuntimeError &e) { perror(e.what()); } //SerialPort.serialPortBufferEmpty(true); break; case SIGINT: // Interactive attention printf("SIGINT serial port !!!\n"); break; case SIGSEGV: printf("Segmentation Fault !!!!\n"); //close(fdSP); //pthread_exit(0x00); break; default: break; } }
int initComm(COMConfig& conf, CSerialPort& sp) { if (!sp.InitPort(conf.num, conf.baud)) { return -1; } return 0; }
int main() { char filepath[20]; Config config; cin >> filepath; if (loadConfig(filepath, config) == 0) { CSerialPort sp; if (initComm(config.com, sp) == 0) { std::cout << "COM" << config.com.num << "opened!" << std::endl; Network net(config.sock); if (net.init()) { while (1) { net.startListen(); while (net.read() != 0) { string res = parseCommand(net.rbuf, config.style); sp.WriteData((unsigned char*)res.c_str(), res.length()); sp.WriteData((unsigned char*)"\r\n"); cout << res << endl; } } } } else { std::cerr << "failed to open COM" << config.com.num << std::endl; return -2; } } else { return -1; } system("pause"); }
DWORD WINAPI CSerialPort::ThreadSend(LPVOID lp) { //JLOG(_T("core dump CSerialPort::ThreadSend tid %d"), GetCurrentThreadId()); CSerialPort *port = static_cast<CSerialPort*>(lp); while (1) { DWORD dwRet = WaitForSingleObject(port->m_hShutdownEvent, 1); if (dwRet == WAIT_OBJECT_0) break; dwRet = WaitForSingleObject(port->m_hEventSent, 0); if (dwRet == WAIT_OBJECT_0) { char sendBuff[128] = { 0 }; WORD wCmdLen = 0; if (port->OnSend(sendBuff, sizeof(sendBuff), wCmdLen) && wCmdLen > 0) { ResetEvent(port->m_hEventSent); port->WriteToPort(sendBuff, wCmdLen); } } } return 0; }
void CPacket::SendNCmd(CSerialPort &port) { strData.Empty(); Command_Packet cmd; cmd.head = STX; cmd.type = 'N'; cmd.endCR = 0x0D; cmd.endLF = 0x0A; cmd.tail = ETX; port.Write((const char*)&cmd,sizeof(cmd)); }
//通过串口发短信 int CAlertMain::SendSmsFromComm(CString strSmsTo, CString strContent) { ODS_DEFINE(_T(" for debug")); ODS_OUTDEBUG(_T("CAlertMain::SendSmsFromComm ... ")); if(bInitSerialPort) { return m_smsPort.SendMsg(strSmsTo, strContent); } return -1; }
int CPacket::ReceiveFrame(CSerialPort &port) { char c=0; strData.Empty(); do { int n=port.Read(&c,1); if (n<0) return -1; else if(n==0) return 0; }while(c != STX); strData+=c; CTime start = CTime::GetCurrentTime(); CTime now; CTimeSpan pause; do { int n = port.Read(&c,1); if (n<0) return -1; else if (n) { start = CTime::GetCurrentTime(); strData+=c; } now = CTime::GetCurrentTime(); pause = now - start; if (pause.GetTotalSeconds() > 5) { strData.Empty(); return 0; } }while(c!=ETX); return strData.GetLength(); }
//打开发短信串口 bool CAlertMain::InitSerialPort() { ODS_DEFINE(_T(" for debug")); ODS_OUTDEBUG(_T("CAlertMain::InitSerialPort ... ")); //串口名称 string sret; string Value = GetIniFileString("SMSCommConfig", "Port", sret, "smsconfig.ini"); CString strCOM = "COM"; strCOM += Value.c_str(); //初始化串口 int nErr = m_smsPort.InitPort(strCOM); if (nErr == 0) return TRUE;//初始化成功 else { switch(nErr) { case CSerialPort::OpenPortFailed://打开端口失败 ODS_OUTDEBUG(_T("初始化COM - 打开端口失败")); break; case CSerialPort::NoSetCenter://没有设置短信中心 ODS_OUTDEBUG(_T("初始化COM - 没有设置短信中心")); break; default: ODS_OUTDEBUG(_T("初始化COM - 未知错误")); break; } m_smsPort.CloseCom(); return FALSE;//初始化失败 } return true; }
/* Save data from cache to corresponding external object(s), * this task COULD be performed in other than GUI thread: */ void UIMachineSettingsSerialPage::saveFromCacheTo(QVariant &data) { /* Fetch data to machine: */ UISettingsPageMachine::fetchData(data); /* Check if ports data was changed: */ if (m_cache.wasChanged()) { /* For each serial port: */ for (int iPort = 0; iPort < mTabWidget->count(); ++iPort) { /* Check if port data was changed: */ const UICacheSettingsMachineSerialPort &portCache = m_cache.child(iPort); if (portCache.wasChanged()) { /* Check if port still valid: */ CSerialPort port = m_machine.GetSerialPort(iPort); if (!port.isNull()) { /* Get port data: */ const UIDataSettingsMachineSerialPort &portData = portCache.data(); /* Store adapter data: */ if (isMachineOffline()) { port.SetEnabled(portData.m_fPortEnabled); port.SetIRQ(portData.m_uIRQ); port.SetIOBase(portData.m_uIOBase); port.SetServer(portData.m_fServer); port.SetPath(portData.m_strPath); /* This *must* be last. The host mode will be changed to disconnected if * some of the necessary settings above will not meet the requirements for * the selected mode. */ port.SetHostMode(portData.m_hostMode); } } } } } /* Upload machine to data: */ UISettingsPageMachine::uploadData(data); }
// // The CommThread Function. ///线程函数 ///监视线程的大致流程: ///检查串口-->进入循环{WaitCommEvent(不阻塞询问)询问事件-->如果有事件来到-->到相应处理(关闭\读\写)} // DWORD WINAPI CSerialPort::CommThread(LPVOID pParam) { // Cast the void pointer passed to the thread back to // a pointer of CSerialPort class CSerialPort *port = (CSerialPort*)pParam; // Set the status variable in the dialog class to // TRUE to indicate the thread is running. ///TRUE表示线程正在运行 port->m_bThreadAlive = TRUE; // Misc. variables DWORD BytesTransfered = 0; DWORD Event = 0; DWORD CommEvent = 0; DWORD dwError = 0; COMSTAT comstat; BOOL bResult = TRUE; // Clear comm buffers at startup ///开始时清除串口缓冲 if (port->m_hComm) // check if the port is opened PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // begin forever loop. This loop will run as long as the thread is alive. ///只要线程存在就不断读取数据 for (;;) { // Make a call to WaitCommEvent(). This call will return immediatly // because our port was created as an async port (FILE_FLAG_OVERLAPPED // and an m_OverlappedStructerlapped structure specified). This call will cause the // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to // be placed in a non-signeled state if there are no bytes available to be read, // or to a signeled state if there are bytes available. If this event handle // is set to the non-signeled state, it will be set to signeled when a // character arrives at the port. // we do this for each port! /* WaitCommEvent函数第3个参数1pOverlapped可以是一个OVERLAPPED结构的变量指针 ,也可以是NULL,当用NULL时,表示该函数是同步的,否则表示该函数是异步的。 调用WaitCommEvent时,如果异步操作不能立即完成,会立即返回FALSE,系统在 WaitCommEvent返回前将OVERLAPPED结构成员hEvent设为无信号状态,等到产生通信 事件时,系统将其置有信号 */ bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov);///表示该函数是异步的 if (!bResult) { // If WaitCommEvent() returns FALSE, process the last error to determin // the reason.. ///如果WaitCommEvent返回Error为FALSE,则查询错误信息 switch (dwError = GetLastError()) { case ERROR_IO_PENDING: ///正常情况,没有字符可读 { // This is a normal return value if there are no bytes // to read at the port. // Do nothing and continue break; } case 87:///系统错误 { // Under Windows NT, this value is returned for some reason. // I have not investigated why, but it is also a valid reply // Also do nothing and continue. break; } default:///发生其他错误,其中有串口读写中断开串口连接的错误 { // All other error codes indicate a serious error has // occured. Process this error. port->ProcessErrorMessage("WaitCommEvent()"); break; } } } else ///WaitCommEvent()能正确返回 { // If WaitCommEvent() returns TRUE, check to be sure there are // actually bytes in the buffer to read. // // If you are reading more than one byte at a time from the buffer // (which this program does not do) you will have the situation occur // where the first byte to arrive will cause the WaitForMultipleObjects() // function to stop waiting. The WaitForMultipleObjects() function // resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state // as it returns. // // If in the time between the reset of this event and the call to // ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again // to the signeled state. When the call to ReadFile() occurs, it will // read all of the bytes from the buffer, and the program will // loop back around to WaitCommEvent(). // // At this point you will be in the situation where m_OverlappedStruct.hEvent is set, // but there are no bytes available to read. If you proceed and call // ReadFile(), it will return immediatly due to the async port setup, but // GetOverlappedResults() will not return until the next character arrives. // // It is not desirable for the GetOverlappedResults() function to be in // this state. The thread shutdown event (event 0) and the WriteFile() // event (Event2) will not work if the thread is blocked by GetOverlappedResults(). // // The solution to this is to check the buffer with a call to ClearCommError(). // This call will reset the event handle, and if there are no bytes to read // we can loop back through WaitCommEvent() again, then proceed. // If there are really bytes to read, do nothing and proceed. bResult = ClearCommError(port->m_hComm, &dwError, &comstat); if (comstat.cbInQue == 0) continue; } // end if bResult ///主等待函数,会阻塞线程 // Main wait function. This function will normally block the thread // until one of nine events occur that require action. ///等待3个事件:关断/读/写,有一个事件发生就返回 Event = WaitForMultipleObjects(3, ///3个事件 port->m_hEventArray, ///事件数组 FALSE, ///有一个事件发生就返回 INFINITE);///超时时间 switch (Event) { case 0: { // Shutdown event. This is event zero so it will be // the higest priority and be serviced first. ///关断事件,关闭串口 CloseHandle(port->m_hComm); port->m_hComm=NULL; port->m_bThreadAlive = FALSE; // Kill this thread. break is not needed, but makes me feel better. //AfxEndThread(100); ::ExitThread(100); break; } case 1: // read event 将定义的各种消息发送出去 { GetCommMask(port->m_hComm, &CommEvent); if (CommEvent & EV_RXCHAR) //接收到字符,并置于输入缓冲区中 ReceiveChar(port); if (CommEvent & EV_CTS) //CTS信号状态发生变化 ::SendMessage(port->m_pOwner, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RXFLAG) //接收到事件字符,并置于输入缓冲区中 ::SendMessage(port->m_pOwner, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_BREAK) //输入中发生中断 ::SendMessage(port->m_pOwner, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_ERR) //发生线路状态错误,线路状态错误包括CE_FRAME,CE_OVERRUN和CE_RXPARITY ::SendMessage(port->m_pOwner, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RING) //检测到振铃指示 ::SendMessage(port->m_pOwner, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); break; } case 2: // write event 发送数据 { // Write character event from port WriteChar(port); break; } default: { AfxMessageBox("接收有问题!"); break; } } // end switch } // close forever loop return 0; }
// // The CommThread Function. // UINT CSerialPort::CommThread(LPVOID pParam) { // Cast the void pointer passed to the thread back to // a pointer of CSerialPort class CSerialPort *port = (CSerialPort*)pParam; // Set the status variable in the dialog class to // TRUE to indicate the thread is running. port->m_bThreadAlive = TRUE; // Misc. variables DWORD BytesTransfered = 0; DWORD Event = 0; DWORD CommEvent = 0; DWORD dwError = 0; static COMSTAT comstat; BOOL bResult = TRUE; // Clear comm buffers at startup if (port->m_hComm) // check if the port is opened PurgeComm(port->m_hComm, PURGE_RXCLEAR | PURGE_TXCLEAR | PURGE_RXABORT | PURGE_TXABORT); // begin forever loop. This loop will run as long as the thread is alive. for (;;) { // Make a call to WaitCommEvent(). This call will return immediatly // because our port was created as an async port (FILE_FLAG_OVERLAPPED // and an m_OverlappedStructerlapped structure specified). This call will cause the // m_OverlappedStructerlapped element m_OverlappedStruct.hEvent, which is part of the m_hEventArray to // be placed in a non-signeled state if there are no bytes available to be read, // or to a signeled state if there are bytes available. If this event handle // is set to the non-signeled state, it will be set to signeled when a // character arrives at the port. // we do this for each port! bResult = WaitCommEvent(port->m_hComm, &Event, &port->m_ov); if (!bResult) { // If WaitCommEvent() returns FALSE, process the last error to determin // the reason.. switch (dwError = GetLastError()) { case ERROR_IO_PENDING: { // This is a normal return value if there are no bytes // to read at the port. // Do nothing and continue break; } case 87: { // Under Windows NT, this value is returned for some reason. // I have not investigated why, but it is also a valid reply // Also do nothing and continue. break; } default: { // All other error codes indicate a serious error has // occured. Process this error. port->ProcessErrorMessage("WaitCommEvent()"); break; } } } else { // If WaitCommEvent() returns TRUE, check to be sure there are // actually bytes in the buffer to read. // // If you are reading more than one byte at a time from the buffer // (which this program does not do) you will have the situation occur // where the first byte to arrive will cause the WaitForMultipleObjects() // function to stop waiting. The WaitForMultipleObjects() function // resets the event handle in m_OverlappedStruct.hEvent to the non-signelead state // as it returns. // // If in the time between the reset of this event and the call to // ReadFile() more bytes arrive, the m_OverlappedStruct.hEvent handle will be set again // to the signeled state. When the call to ReadFile() occurs, it will // read all of the bytes from the buffer, and the program will // loop back around to WaitCommEvent(). // // At this point you will be in the situation where m_OverlappedStruct.hEvent is set, // but there are no bytes available to read. If you proceed and call // ReadFile(), it will return immediatly due to the async port setup, but // GetOverlappedResults() will not return until the next character arrives. // // It is not desirable for the GetOverlappedResults() function to be in // this state. The thread shutdown event (event 0) and the WriteFile() // event (Event2) will not work if the thread is blocked by GetOverlappedResults(). // // The solution to this is to check the buffer with a call to ClearCommError(). // This call will reset the event handle, and if there are no bytes to read // we can loop back through WaitCommEvent() again, then proceed. // If there are really bytes to read, do nothing and proceed. bResult = ClearCommError(port->m_hComm, &dwError, &comstat); if (comstat.cbInQue == 0) continue; } // end if bResult // Main wait function. This function will normally block the thread // until one of nine events occur that require action. Event = WaitForMultipleObjects(3, port->m_hEventArray, FALSE, INFINITE); switch (Event) { case 0: { // Shutdown event. This is event zero so it will be // the higest priority and be serviced first. port->m_bThreadAlive = FALSE; // Kill this thread. break is not needed, but makes me feel better. AfxEndThread(100); break; } case 1: // read event { GetCommMask(port->m_hComm, &CommEvent); if (CommEvent & EV_CTS) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_CTS_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RXFLAG) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RXFLAG_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_BREAK) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_BREAK_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_ERR) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_ERR_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RING) ::SendMessage(port->m_pOwner->m_hWnd, WM_COMM_RING_DETECTED, (WPARAM) 0, (LPARAM) port->m_nPortNr); if (CommEvent & EV_RXCHAR) // Receive character event from port. ReceiveChar(port, comstat); break; } case 2: // write event { // Write character event from port WriteChar(port); break; } } // end switch } // close forever loop return 0; }
int main() { GOOGLE_PROTOBUF_VERIFY_VERSION; //define variable WSADATA wsaData; SOCKET hServerSock, hClientSock; SOCKADDR_IN serverAddr, clientAddr; Sensor sensor; CSerialPort port; int sizeClientAddr; int n; int result; bool GoOn = true; //Serial port setup port.Open(PORT_NAME, CBR_9600, 8, ONESTOPBIT, NOPARITY); port.SetTimeout(10, 10, 1); char message[] = "Hello World!"; //WSAStart result = WSAStartup(MAKEWORD(2, 2), &wsaData); if (result != 0) { ErrorHandling("WSAStartup() error"); } //socket open hServerSock = socket(PF_INET, SOCK_STREAM, 0); if (hServerSock == INVALID_SOCKET) { ErrorHandling("socket() error"); } //bind socket with port memset(&serverAddr, 0, sizeof(serverAddr)); serverAddr.sin_family = AF_INET; serverAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); serverAddr.sin_port = htons(atoi("9000")); result = bind(hServerSock, (SOCKADDR*)&serverAddr, sizeof(serverAddr)); if (result == SOCKET_ERROR) { ErrorHandling("bind() error"); } //listen result = listen(hServerSock, 5); if (result == SOCKET_ERROR) { ErrorHandling("listen() error"); } //accept client sizeClientAddr = sizeof(clientAddr); hClientSock = accept(hServerSock, (SOCKADDR*)&clientAddr, &sizeClientAddr); if (hClientSock == INVALID_SOCKET) { ErrorHandling("accept() error"); } std::cout << "connected" << std::endl; char serialBuffer[BUFSIZ]; char tcpBuffer[BUFSIZ]; int realSize = 0; float f; bool isRight = false; bool sec = false; std::string buf1; std::string buf2; std::stringbuf buffer; std::ostream os(&buffer); sensor.SerializeToOstream(&os); port.Flush(); port.Read(serialBuffer, BUFSIZ); while (GoOn) { /*while (!sec) { if (!isRight) { do { realSize = port.Read(serialBuffer, BUFSIZ); strcount = 0; stringBuffer[0] = serialBuffer[strcount]; strcount++; } while (*stringBuffer != '\n'); isRight = true; } i = 0; sec = true; while (true) { do { if (realSize - strcount < 1) { realSize = port.Read(serialBuffer, BUFSIZ); strcount = 0; } stringBuffer[i] = serialBuffer[strcount]; strcount++; } while (stringBuffer[i] < 0); if ((stringBuffer[i] == '\n') && i > 0) { stringBuffer[i] = '\0'; break; } ++i; } } sec = false;*/ realSize = port.Read(serialBuffer, BUFSIZ); std::string buff1 = serialBuffer; std::string pch2 = buff1.substr(0, realSize); std::string s = pch2.substr(pch2.find_first_of('\n') + 1); s = s.substr(0, s.find_first_of('\n')); std::cout << "Parsed: " << s << std::endl; try { f = std::stof(s.substr(0, s.find_first_of(','))); sensor.set_arg0(f); s = s.substr(s.find_first_of(',') + 1); f = std::stof(s.substr(0, s.find_first_of(','))); sensor.set_arg1(f); s = s.substr(s.find_first_of(',') + 1); f = std::stof(s.substr(0, s.find_first_of(','))); sensor.set_arg2(f); s = s.substr(s.find_first_of(',') + 1); f = std::stof(s.substr(0, s.find_first_of(','))); sensor.set_arg3(f); s = s.substr(s.find_first_of(',') + 1); f = std::stof(s.substr(0, s.find_first_of(','))); sensor.set_arg4(f); s = s.substr(s.find_first_of(',') + 1); sensor.SerializeToArray(tcpBuffer, BUFSIZ); //message send } catch (std::exception e) { isRight = false; continue; } try { send(hClientSock, tcpBuffer, sensor.ByteSize(), 0); } catch (std::exception e) { std::cout << "cannot send data!" << std::endl; continue; } std::cout << "send: " << sensor.ByteSize() << std::endl; int j = 0; while (j != 100000000) { j++; } } //close socket closesocket(hClientSock); port.Close(); closesocket(hServerSock); WSACleanup(); return 0; }
void CComSetting::OnbtnApply() { // TODO: Add your control notification handler code here /* if ( -1 < m_cboPort.GetCurSel() ) { g_pMainThis->m_mscom.SetCommPort( m_cboPort.GetCurSel() + 1 ); } g_pMainThis->m_mscom.SetInBufferSize( 1024 ); g_pMainThis->m_mscom.SetOutBufferSize( 512 ); g_pMainThis->m_mscom.SetInputMode( 1 ); CString szSpeed; m_cboSpeed.GetWindowText( szSpeed ); TRACE( "szSpeed:%s\r\n", szSpeed ); CString szParity; m_cboParity.GetWindowText( szParity ); szParity.MakeLower(); szParity = szParity.GetAt( 0 ); TRACE( "szParity:%s\r\n", szParity ); CString szDataBits; m_cboDataBits.GetWindowText( szDataBits ); TRACE( "szDataBits:%s\r\n", szDataBits ); CString szStopBits; m_cboStopBits.GetWindowText( szStopBits ); TRACE( "szStopBits:%s\r\n", szStopBits ); char szSet[50]; sprintf_s( szSet, "%s,%s,%s,%s", szSpeed, szParity, szDataBits, szStopBits ); TRACE( "szSet:%s\r\n", szSet ); g_pMainThis->m_mscom.SetSettings( szSet ); g_pMainThis->m_mscom.SetRThreshold( 1 ); g_pMainThis->m_mscom.SetInputLen( 0 ); */ BYTE* pBuf = new BYTE[10000]; try { COMMCONFIG config; CSerialPort::GetDefaultConfig(1, config); CSerialPort port; port.Open(1, 1200, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl); HANDLE hPort = port.Detach(); port.Attach(hPort); DWORD dwModemStatus; port.GetModemStatus(dwModemStatus); DCB dcb; port.GetState(dcb); dcb.BaudRate = 9600; port.SetState(dcb); DWORD dwErrors; port.ClearError(dwErrors); /* port.SetBreak(); port.ClearBreak(); */ COMSTAT stat; port.GetStatus(stat); DWORD dwBytesWaiting = port.BytesWaiting(); dwBytesWaiting; COMMTIMEOUTS timeouts; port.GetTimeouts(timeouts); port.Setup(10000, 10000); port.GetConfig(config); config.dcb.BaudRate = 9600; port.SetConfig(config); port.Set0WriteTimeout(); port.Set0ReadTimeout(); char sBuf[] = "This should appear on the serial port"; port.Write(sBuf, static_cast<DWORD>(strlen(sBuf))); DWORD dwMask; port.GetMask(dwMask); port.SetMask(EV_TXEMPTY); //port.WaitEvent(dwMask); //使用常量PURGE_TXABORT调用Purge,终止所有写操作,并立即返回,无论写操作有没有完成 port.TerminateOutstandingWrites(); /* //最高的优先权发送一个字符 port.TransmitChar('p'); */ //发送和接受超时配置为0 port.Set0Timeout(); char sRxBuf[10]; DWORD dwRead = port.Read(sRxBuf, 10); dwRead; //To remove unreferrenced variable in VC 6. port.TerminateOutstandingReads(); port.ClearDTR(); port.ClearRTS(); port.SetDTR(); port.SetRTS(); port.SetXOFF(); port.SetXON(); COMMPROP properties; port.GetProperties(properties); port.ClearWriteBuffer(); port.ClearReadBuffer(); port.Flush(); port.Close(); /* //Try out the overlapped functions CSerialPort port2; port2.Open(1, 9600, CSerialPort::NoParity, 8, CSerialPort::OneStopBit, CSerialPort::XonXoffFlowControl, TRUE); CEvent event(FALSE, TRUE); OVERLAPPED overlapped; memset(&overlapped, 0, sizeof(overlapped)); overlapped.hEvent = event; try { port2.Write(pBuf, 10000, overlapped); } catch(CSerialException* pEx) { if (pEx->m_dwError == ERROR_IO_PENDING) { DWORD dwBytesTransferred = 0; port2.GetOverlappedResult(overlapped, dwBytesTransferred, TRUE); pEx->Delete(); } else { DWORD dwError = pEx->m_dwError; pEx->Delete(); CSerialPort::ThrowSerialException(dwError); } } try { port2.Read(pBuf, 10, overlapped); } catch(CSerialException* pEx) { if (pEx->m_dwError == ERROR_IO_PENDING) { DWORD dwBytesTransferred = 0; port2.GetOverlappedResult(overlapped, dwBytesTransferred, TRUE); pEx->Delete(); } else { DWORD dwError = pEx->m_dwError; pEx->Delete(); CSerialPort::ThrowSerialException(dwError); } } port2.SetMask(EV_TXEMPTY); */ /* for testing on NT only port2.WriteEx(sBuf, static_cast<DWORD>(strlen(sBuf))); SleepEx(INFINITE, TRUE); port2.ReadEx(pBuf, 10); SleepEx(INFINITE, TRUE); */ } catch (CSerialException* pEx) { TRACE(_T("Handle Exception, Message:%s\r\n"), pEx->GetErrorMessage().operator LPCTSTR()); pEx->Delete(); } delete [] pBuf; }
void CPacket::SendAck(CSerialPort &port) { strData.Empty(); strData = ACK; port.Write(strData,1); }