void CNullModem::handleUpperEvent(Bit16u type) { switch(type) { case SERIAL_POLLING_EVENT: { // periodically check if new data arrived, disconnect // if required. Add it back. setEvent(SERIAL_POLLING_EVENT, 1.0f); // update Modem input line states updateMSR(); switch(rx_state) { case N_RX_IDLE: if (CanReceiveByte()) { if (doReceive()) { // a byte was received rx_state=N_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } // else still idle } else { #if SERIAL_DEBUG log_ser(dbg_aux,"Nullmodem: block on polling."); #endif rx_state=N_RX_BLOCKED; // have both delays (1ms + bytetime) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } break; case N_RX_BLOCKED: // one timeout tick if (!CanReceiveByte()) { rx_retry++; if (rx_retry>=rx_retry_max) { // it has timed out: rx_retry=0; removeEvent(SERIAL_RX_EVENT); if (doReceive()) { // read away everything while(doReceive()); rx_state=N_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } else { // much trouble about nothing rx_state=N_RX_IDLE; #if SERIAL_DEBUG log_ser(dbg_aux,"Nullmodem: unblock due to no more data",rx_retry); #endif } } // else wait further } else { // good: we can receive again removeEvent(SERIAL_RX_EVENT); rx_retry=0; if (doReceive()) { rx_state=N_RX_FASTWAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.65f); } else { // much trouble about nothing rx_state=N_RX_IDLE; } } break; case N_RX_WAIT: case N_RX_FASTWAIT: break; } break; } case SERIAL_RX_EVENT: { switch(rx_state) { case N_RX_IDLE: LOG_MSG("internal error in nullmodem"); break; case N_RX_BLOCKED: // try to receive case N_RX_WAIT: case N_RX_FASTWAIT: if (CanReceiveByte()) { // just works or unblocked if (doReceive()) { rx_retry=0; // not waiting anymore if (rx_state==N_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); else { // maybe unblocked rx_state=N_RX_FASTWAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.65f); } } else { // didn't receive anything rx_retry=0; rx_state=N_RX_IDLE; } } else { // blocking now or still blocked #if SERIAL_DEBUG if (rx_state==N_RX_BLOCKED) log_ser(dbg_aux,"Nullmodem: rx still blocked (retry=%d)",rx_retry); else log_ser(dbg_aux,"Nullmodem: block on continued rx (retry=%d).",rx_retry); #endif setEvent(SERIAL_RX_EVENT, bytetime*0.65f); rx_state=N_RX_BLOCKED; } break; } break; } case SERIAL_TX_EVENT: { // Maybe echo cirquit works a bit better this way if (rx_state==N_RX_IDLE && CanReceiveByte() && clientsocket) { if (doReceive()) { // a byte was received rx_state=N_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } } ByteTransmitted(); break; } case SERIAL_THR_EVENT: { ByteTransmitting(); // actually send it setEvent(SERIAL_TX_EVENT,bytetime+0.01f); break; } case SERIAL_SERVER_POLLING_EVENT: { // As long as nothing is connected to our server poll the // connection. if (!ServerConnect()) { // continue looking setEvent(SERIAL_SERVER_POLLING_EVENT, 50); } break; } case SERIAL_TX_REDUCTION: { // Flush the data in the transmitting buffer. if (clientsocket) clientsocket->FlushBuffer(); tx_block=false; break; } case SERIAL_NULLMODEM_DTR_EVENT: { if ((!DTR_delta) && getDTR()) { // DTR went positive. Try to connect. if (ClientConnect(new TCPClientSocket((char*)hostnamebuffer, (Bit16u)clientport))) break; // no more DTR wait event when connected } DTR_delta = getDTR(); setEvent(SERIAL_NULLMODEM_DTR_EVENT,50); break; } } }
void CDirectSerial::handleUpperEvent(Bit16u type) { switch(type) { case SERIAL_POLLING_EVENT: { setEvent(SERIAL_POLLING_EVENT, 1.0f); // update Modem input line states switch(rx_state) { case D_RX_IDLE: if(CanReceiveByte()) { if(doReceive()) { // a byte was received rx_state=D_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } // else still idle } else { #if SERIAL_DEBUG if(!dbgmsg_poll_block) { log_ser(dbg_aux,"Directserial: block on polling."); dbgmsg_poll_block=true; } #endif rx_state=D_RX_BLOCKED; // have both delays (1ms + bytetime) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } break; case D_RX_BLOCKED: // one timeout tick if(!CanReceiveByte()) { rx_retry++; if(rx_retry>=rx_retry_max) { // it has timed out: rx_retry=0; removeEvent(SERIAL_RX_EVENT); if(doReceive()) { // read away everything // this will set overrun errors while(doReceive()); rx_state=D_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } else { // much trouble about nothing rx_state=D_RX_IDLE; } } // else wait further } else { // good: we can receive again #if SERIAL_DEBUG dbgmsg_poll_block=false; dbgmsg_rx_block=false; #endif removeEvent(SERIAL_RX_EVENT); rx_retry=0; if(doReceive()) { rx_state=D_RX_FASTWAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.65f); } else { // much trouble about nothing rx_state=D_RX_IDLE; } } break; case D_RX_WAIT: case D_RX_FASTWAIT: break; } updateMSR(); break; } case SERIAL_RX_EVENT: { switch(rx_state) { case D_RX_IDLE: LOG_MSG("internal error in directserial"); break; case D_RX_BLOCKED: // try to receive case D_RX_WAIT: case D_RX_FASTWAIT: if(CanReceiveByte()) { // just works or unblocked rx_retry=0; // not waiting anymore if(doReceive()) { if(rx_state==D_RX_WAIT) setEvent(SERIAL_RX_EVENT, bytetime*0.9f); else { // maybe unblocked rx_state=D_RX_FASTWAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.65f); } } else { // didn't receive anything rx_state=D_RX_IDLE; } } else { // blocking now or still blocked #if SERIAL_DEBUG if(rx_state==D_RX_BLOCKED) { if(!dbgmsg_rx_block) { log_ser(dbg_aux,"Directserial: rx still blocked (retry=%d)",rx_retry); dbgmsg_rx_block=true; } } else log_ser(dbg_aux,"Directserial: block on continued rx (retry=%d).",rx_retry); #endif setEvent(SERIAL_RX_EVENT, bytetime*0.65f); rx_state=D_RX_BLOCKED; } break; } updateMSR(); break; } case SERIAL_TX_EVENT: { // Maybe echo cirquit works a bit better this way if(rx_state==D_RX_IDLE && CanReceiveByte()) { if(doReceive()) { // a byte was received rx_state=D_RX_WAIT; setEvent(SERIAL_RX_EVENT, bytetime*0.9f); } } ByteTransmitted(); updateMSR(); break; } case SERIAL_THR_EVENT: { ByteTransmitting(); setEvent(SERIAL_TX_EVENT,bytetime*1.1f); break; } } }
void CDirectSerial::Timer2(void) { ULONG dwRead = 0; USHORT errors = 0; Bit8u chRead = 0; ULONG ulParmLen = sizeof(errors); if (lastChance == 0) { // lastChance = 0 if (CanReceiveByte ()) { if (DosRead (hCom, &chRead, 1, &dwRead)) { if (dwRead) receiveByte (chRead); } } else { if (DosRead (hCom, &chRead, 1, &dwRead)) { if (dwRead) { ChanceChar = chRead; lastChance++; } } } } else if (lastChance > 10) { receiveByte (0); // this causes RX Overrun now lastChance = 0; // empty serial buffer dwRead = 1; while (dwRead > 0) { // throw away bytes in buffer DosRead (hCom, &chRead, 1, &dwRead); } } else { // lastChance>0 // already one waiting if (CanReceiveByte ()) { // chance used receiveByte (ChanceChar); lastChance = 0; } else lastChance++; } // check for errors Bit8u errreg = 0; APIRET rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMERROR, 0, 0, 0, &errors, ulParmLen, &ulParmLen); if (rc != NO_ERROR && errors) { if (errors & 8) { LOG_MSG ("Serial port at 0x%x: line error: framing error.", base); errreg |= LSR_FRAMING_ERROR_MASK; } if (errors & 4) { LOG_MSG ("Serial port at 0x%x: line error: parity error.", base); errreg |= LSR_PARITY_ERROR_MASK; } } errors = 0; rc = DosDevIOCtl(hCom, IOCTL_ASYNC, ASYNC_GETCOMMEVENT, 0, 0, 0, &errors, ulParmLen, &ulParmLen); if (rc != NO_ERROR && errors) { if (errors & 6) { LOG_MSG ("Serial port at 0x%x: line error: break received.", base); errreg |= LSR_RX_BREAK_MASK; } } if (errreg != 0) { receiveError (errreg); } // update Modem input line states updateMSR (); }