Пример #1
0
Bits CNullModem::readChar() {
	Bits rxchar = clientsocket->GetcharNonBlock();
	if (telnet && rxchar>=0) return TelnetEmulation((Bit8u)rxchar);
	else if (rxchar==0xff && !transparent) {// escape char
		// get the next char
		Bits rxchar = clientsocket->GetcharNonBlock();
		if (rxchar==0xff) return rxchar; // 0xff 0xff -> 0xff was meant
		rxchar&0x1? setCTS(true) : setCTS(false);
		rxchar&0x2? setDSR(true) : setDSR(false);
		if (rxchar&0x4) receiveByteEx(0x0,0x10);
		return -1;	// no "payload" received
	} else return rxchar;
}
Пример #2
0
void CSerialModem::Timer2(void) {

	unsigned long args = 1;
	bool sendbyte = true;
	Bitu usesize;
	Bit8u txval;
	Bitu txbuffersize =0;

	// Check for eventual break command
	if (!commandmode) cmdpause++;
	// Handle incoming data from serial port, read as much as available
	CSerial::setCTS(true);	// buffer will get 'emptier', new data can be received 
	while (tqueue->inuse()) {
		txval = tqueue->getb();
		if (commandmode) {
			if (echo) {
				rqueue->addb(txval);
				//LOG_MSG("Echo back to queue: %x",txval);
			}
			if (txval==0xa) continue;		//Real modem doesn't seem to skip this?
			else if (txval==0x8 && (cmdpos > 0)) --cmdpos;	// backspace
			else if (txval==0xd) DoCommand();				// return
			else if (txval != '+') {
				if(cmdpos<99) {
					cmdbuf[cmdpos] = txval;
					cmdpos++;
				}
			}
		}
		else {// + character
			// 1000 ticks have passed, can check for pause command
			if (cmdpause > 1000) {
				if(txval ==reg[MREG_ESCAPE_CHAR]) // +
				{
					plusinc++;
					if(plusinc>=3) {
						LOG_MSG("Modem: Entering command mode(escape sequence)");
						commandmode = true;
						SendRes(ResOK);
						plusinc = 0;
					}
					sendbyte=false;
				} else {
					plusinc=0;
				}
	// If not a special pause command, should go for bigger blocks to send 
			}
			tmpbuf[txbuffersize] = txval;
			txbuffersize++;
		}
	} // while loop
	
	if (clientsocket && sendbyte && txbuffersize) {
		// down here it saves a lot of network traffic
		if(!clientsocket->SendArray(tmpbuf,txbuffersize)) {
			SendRes(ResNOCARRIER);
			EnterIdleState();
		}
	}
	// Handle incoming to the serial port
	if(!commandmode && clientsocket && rqueue->left()) {
		usesize = rqueue->left();
		if (usesize>16) usesize=16;
		if(!clientsocket->ReceiveArray(tmpbuf, &usesize)) {
			SendRes(ResNOCARRIER);
			EnterIdleState();
		} else if(usesize) {
			// Filter telnet commands 
			if(telnetmode) TelnetEmulation(tmpbuf, usesize);
			else rqueue->adds(tmpbuf,usesize);
			cmdpause = 0;
		} 
	}
	// Check for incoming calls
	if (!connected && !waitingclientsocket && serversocket) {
		waitingclientsocket=serversocket->Accept();
		if(waitingclientsocket) {	
			if(!CSerial::getDTR()) {
				// accept no calls with DTR off; TODO: AT &Dn
				EnterIdleState();
			} else {
				ringing=true;
				SendRes(ResRING);
				CSerial::setRI(!CSerial::getRI());
				//MIXER_Enable(mhd.chan,true);
				ringtimer = 3000;
				reg[1] = 0;		//Reset ring counter reg
			}
		}
	}
	if (ringing) {
		if (ringtimer <= 0) {
			reg[1]++;
			if ((reg[0]>0) && (reg[0]>=reg[1])) {
				AcceptIncomingCall();
				return;
			}
			SendRes(ResRING);
			CSerial::setRI(!CSerial::getRI());

			//MIXER_Enable(mhd.chan,true);
			ringtimer = 3000;
		}
		--ringtimer;
	}
}