Beispiel #1
0
CSerialModem::CSerialModem(Bitu id, CommandLine* cmd):CSerial(id, cmd) {
	InstallationSuccessful=false;
	connected=false;

	rqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE);
	tqueue=new CFifo(MODEM_BUFFER_QUEUE_SIZE);
	
	// Default to direct null modem connection.  Telnet mode interprets IAC codes
	telnetmode = false;

	// Initialize the sockets and setup the listening port
	listenport = 23;
	waitingclientsocket=0;
	clientsocket = 0;
	serversocket = 0;
	getBituSubstring("listenport:", &listenport, cmd);
	
	// TODO: Fix dialtones if requested
	//mhd.chan=MIXER_AddChannel((MIXER_MixHandler)this->MODEM_CallBack,8000,"MODEM");
	//MIXER_Enable(mhd.chan,false);
	//MIXER_SetMode(mhd.chan,MIXER_16MONO);
		
	CSerial::Init_Registers();
	Reset(); // reset calls EnterIdleState
		
	setEvent(SERIAL_POLLING_EVENT,1);
	InstallationSuccessful=true;
}
Beispiel #2
0
CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd)
					:CSerial (id, cmd) {
	InstallationSuccessful = false;
	comport = 0;

	rx_retry = 0;
    rx_retry_max = 0;

	std::string tmpstring;
	if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;

	LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
	if(!SERIAL_open(tmpstring.c_str(), &comport)) {
		char errorbuffer[256];
		SERIAL_getErrorString(errorbuffer, sizeof(errorbuffer));
		LOG_MSG("Serial%d: Serial Port \"%s\" could not be opened.",
			COMNUMBER, tmpstring.c_str());
		LOG_MSG("%s",errorbuffer);
		return;
	}

#if SERIAL_DEBUG
	dbgmsg_poll_block=false;
	dbgmsg_rx_block=false;
#endif

	// rxdelay: How many milliseconds to wait before causing an
	// overflow when the application is unresponsive.
	if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
		if(!(rx_retry_max<=10000)) {
			rx_retry_max=0;
		}
	}

	CSerial::Init_Registers();
	InstallationSuccessful = true;
	rx_state = D_RX_IDLE;
	setEvent(SERIAL_POLLING_EVENT, 1); // millisecond receive tick
}
CDirectSerial::CDirectSerial (Bitu id, CommandLine* cmd)
					:CSerial (id, cmd) {
	InstallationSuccessful = false;
	hCom = INVALID_HANDLE_VALUE; // else destructor may close an invalid handle
	rx_retry = 0;
    rx_retry_max = 0;

	// open the port in NT object space (recommended by Microsoft)
	// allows the user to open COM10+ and custom port names.
	std::string prefix="\\\\.\\";
	std::string tmpstring;
	if(!cmd->FindStringBegin("realport:",tmpstring,false)) return;

#if SERIAL_DEBUG
		if(dbg_modemcontrol)
			fprintf(debugfp,"%12.3f Port type directserial realport %s\r\n",
				PIC_FullIndex(),tmpstring.c_str());
#endif

	prefix.append(tmpstring);

	// rxdelay: How many milliseconds to wait before causing an
	// overflow when the application is unresponsive.
	if(getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
		if(!(rx_retry_max<=10000)) {
			rx_retry_max=0;
		}
	}

	const char* tmpchar=prefix.c_str();

	LOG_MSG ("Serial%d: Opening %s", COMNUMBER, tmpstring.c_str());
	hCom = CreateFile (tmpchar,
					   GENERIC_READ | GENERIC_WRITE, 0,
									  // must be opened with exclusive-access
	                   NULL,          // no security attributes
	                   OPEN_EXISTING, // must use OPEN_EXISTING
	                   0,             // non overlapped I/O
	                   NULL           // hTemplate must be NULL for comm devices
	                  );

	if (hCom == INVALID_HANDLE_VALUE) {
		int error = GetLastError ();
		LOG_MSG ("Serial%d: Serial Port \"%s\" could not be opened.",
			COMNUMBER, tmpstring.c_str());
		if (error == 2) {
			LOG_MSG ("The specified port does not exist.");
		} else if (error == 5) {
			LOG_MSG ("The specified port is already in use.");
		} else {
			LOG_MSG ("Windows error %d occurred.", error);
		}
		return;
	}

	dcb.DCBlength=sizeof(dcb);
	fSuccess = GetCommState (hCom, &dcb);

	if (!fSuccess) {
		// Handle the error.
		LOG_MSG ("GetCommState failed with error %d.\n", (int)GetLastError ());
		hCom = INVALID_HANDLE_VALUE;
		return;
	}

	// initialize the port
	dcb.BaudRate=CBR_9600;
	dcb.fBinary=true;
	dcb.fParity=true;
	dcb.fOutxCtsFlow=false;
	dcb.fOutxDsrFlow=false;
	dcb.fDtrControl=DTR_CONTROL_DISABLE;
	dcb.fDsrSensitivity=false;
	
	dcb.fOutX=false;
	dcb.fInX=false;
	dcb.fErrorChar=0;
	dcb.fNull=false;
	dcb.fRtsControl=RTS_CONTROL_DISABLE;
	dcb.fAbortOnError=false;

	dcb.ByteSize=8;
	dcb.Parity=NOPARITY;
	dcb.StopBits=ONESTOPBIT;

	fSuccess = SetCommState (hCom, &dcb);

	if (!fSuccess) {
		// Handle the error.
		LOG_MSG ("SetCommState failed with error %d.\n", (int)GetLastError ());
		hCom = INVALID_HANDLE_VALUE;
		return;
	}

	// Configure timeouts to effectively use polling
	COMMTIMEOUTS ct;
	ct.ReadIntervalTimeout = MAXDWORD;
	ct.ReadTotalTimeoutConstant = 0;
	ct.ReadTotalTimeoutMultiplier = 0;
	ct.WriteTotalTimeoutConstant = 0;
	ct.WriteTotalTimeoutMultiplier = 0;
	SetCommTimeouts (hCom, &ct);

	CSerial::Init_Registers();
	InstallationSuccessful = true;
	receiveblock=false;

	ClearCommBreak (hCom);
	setEvent(SERIAL_POLLING_EVENT, 1); // millisecond tick
}
Beispiel #4
0
CNullModem::CNullModem(Bitu id, CommandLine* cmd):CSerial (id, cmd) {
	Bitu temptcpport=23;
	memset(&telClient, 0, sizeof(telClient));
	InstallationSuccessful = false;
	serversocket = 0;
	clientsocket = 0;
	serverport = 0;
	clientport = 0;

	rx_retry = 0;
	rx_retry_max = 20;
	rx_state=N_RX_DISC;

	tx_gather = 12;
	
	dtrrespect=false;
	tx_block=false;
	receiveblock=false;
	transparent=false;
	telnet=false;
	
	Bitu bool_temp=0;

	// usedtr: The nullmodem will
	// 1) when it is client connect to the server not immediately but
	//    as soon as a modem-aware application is started (DTR is switched on).
	// 2) only receive data when DTR is on.
	if (getBituSubstring("usedtr:", &bool_temp, cmd)) {
		if (bool_temp==1) {
			dtrrespect=true;
			transparent=true;
			DTR_delta=false; // connect immediately when DTR is already 1
		}
	}
	// transparent: don't add additional handshake control.
	if (getBituSubstring("transparent:", &bool_temp, cmd)) {
		if (bool_temp==1) transparent=true;
		else transparent=false;
	}
	// telnet: interpret telnet commands.
	if (getBituSubstring("telnet:", &bool_temp, cmd)) {
		if (bool_temp==1) {
			transparent=true;
			telnet=true;
		}
	}
	// rxdelay: How many milliseconds to wait before causing an
	// overflow when the application is unresponsive.
	if (getBituSubstring("rxdelay:", &rx_retry_max, cmd)) {
		if (!(rx_retry_max<=10000)) {
			rx_retry_max=50;
		}
	}
	// txdelay: How many milliseconds to wait before sending data.
	// This reduces network overhead quite a lot.
	if (getBituSubstring("txdelay:", &tx_gather, cmd)) {
		if (!(tx_gather<=500)) {
			tx_gather=12;
		}
	}
	// port is for both server and client
	if (getBituSubstring("port:", &temptcpport, cmd)) {
		if (!(temptcpport>0&&temptcpport<65536)) {
			temptcpport=23;
		}
	}
	// socket inheritance (client-alike)
	if (getBituSubstring("inhsocket:", &bool_temp, cmd)) {
#ifdef NATIVESOCKETS
		if (Netwrapper_GetCapabilities()&NETWRAPPER_TCP_NATIVESOCKET) {
			if (bool_temp==1) {
				int sock;
				if (control->cmdline->FindInt("-socket",sock,true)) {
					dtrrespect=false;
					transparent=true;
					LOG_MSG("Inheritance socket handle: %d",sock);
					if (!ClientConnect(new TCPClientSocket(sock)))
						return;
				} else {
					LOG_MSG("Serial%d: -socket parameter missing.",COMNUMBER);
					return;
				}
			}
		} else {
			LOG_MSG("Serial%d: socket inheritance not supported on this platform.",
				COMNUMBER);
			return;
		}
#else
		LOG_MSG("Serial%d: socket inheritance not available.", COMNUMBER);
#endif
	} else {
		// normal server/client
		std::string tmpstring;
		if (cmd->FindStringBegin("server:",tmpstring,false)) {
			// we are a client
			const char* hostnamechar=tmpstring.c_str();
			size_t hostlen=strlen(hostnamechar)+1;
			if (hostlen>sizeof(hostnamebuffer)) {
				hostlen=sizeof(hostnamebuffer);
				hostnamebuffer[sizeof(hostnamebuffer)-1]=0;
			}
			memcpy(hostnamebuffer,hostnamechar,hostlen);
			clientport=(Bit16u)temptcpport;
			if (dtrrespect) {
				// we connect as soon as DTR is switched on
				setEvent(SERIAL_NULLMODEM_DTR_EVENT, 50);
				LOG_MSG("Serial%d: Waiting for DTR...",COMNUMBER);
			} else if (!ClientConnect(
				new TCPClientSocket((char*)hostnamebuffer,(Bit16u)clientport)))
				return;
		} else {
			// we are a server
			serverport = (Bit16u)temptcpport;
			if (!ServerListen()) return;
		}
	}
	CSerial::Init_Registers();
	InstallationSuccessful = true;

	setCTS(dtrrespect||transparent);
	setDSR(dtrrespect||transparent);
	setRI(false);
	setCD(clientsocket > 0); // CD on if connection established
}