1 /*
2  *  Copyright (C) 2002-2021  The DOSBox Team
3  *
4  *  This program is free software; you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation; either version 2 of the License, or
7  *  (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License along
15  *  with this program; if not, write to the Free Software Foundation, Inc.,
16  *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  */
18 
19 
20 // include guard
21 #ifndef DOSBOX_NULLMODEM_WIN32_H
22 #define DOSBOX_NULLMODEM_WIN32_H
23 
24 #include "dosbox.h"
25 
26 #if C_MODEM
27 
28 #include "misc_util.h"
29 #include "serialport.h"
30 
31 #define SERIAL_SERVER_POLLING_EVENT	SERIAL_BASE_EVENT_COUNT+1
32 #define SERIAL_TX_REDUCTION		SERIAL_BASE_EVENT_COUNT+2
33 #define SERIAL_NULLMODEM_DTR_EVENT	SERIAL_BASE_EVENT_COUNT+3
34 #define SERIAL_NULLMODEM_EVENT_COUNT	SERIAL_BASE_EVENT_COUNT+3
35 
36 class CNullModem final : public CSerial {
37 public:
38 	CNullModem(const CNullModem &) = delete;            // prevent copying
39 	CNullModem &operator=(const CNullModem &) = delete; // prevent assignment
40 
41 	CNullModem(const uint8_t port_idx, CommandLine *cmd);
42 	~CNullModem();
43 
44 	void updatePortConfig(uint16_t divider, uint8_t lcr);
45 	void updateMSR();
46 	void transmitByte(uint8_t val, bool first);
47 	void setBreak(bool value);
48 
49 	void setRTSDTR(bool rts, bool dtr);
50 	void setRTS(bool val);
51 	void setDTR(bool val);
52 	void handleUpperEvent(uint16_t type);
53 
54 	SocketTypesE socketType = SOCKET_TYPE_TCP;
55 
56 private:
57 	NETServerSocket *serversocket = nullptr;
58 	NETClientSocket *clientsocket = nullptr;
59 
60 	uint16_t serverport = 0; // we are a server if this is nonzero
61 	uint16_t clientport = 0;
62 
63 	uint8_t hostnamebuffer[128] = {0}; // the name passed to us by the user
64 
65 	uint32_t rx_state = 0;
66 #define N_RX_IDLE		0
67 #define N_RX_WAIT		1
68 #define N_RX_BLOCKED	2
69 #define N_RX_FASTWAIT	3
70 #define N_RX_DISC		4
71 
72 	bool doReceive();
73 	bool ClientConnect(NETClientSocket *newsocket);
74 	bool ServerListen();
75 	bool ServerConnect();
76     void Disconnect();
77     SocketState readChar(uint8_t &val);
78     void WriteChar(uint8_t data);
79 
80 	bool DTR_delta = false; // with dtrrespect, we try to establish a
81 	                        // connection whenever DTR switches to 1. This
82 	                        // variable is used to remember the old state.
83 
84 	bool tx_block = false; // true while the SERIAL_TX_REDUCTION event
85 	                       // is pending
86 
87 	uint32_t rx_retry = 0; // counter of retries
88 
89 	uint32_t rx_retry_max = 0; // how many POLL_EVENTS to wait before
90 	                           // causing a overrun error.
91 
92 	uint32_t tx_gather = 0; // how long to gather tx data before
93 	                        // sending all of them [milliseconds]
94 
95 	bool dtrrespect = false; // dtr behavior - only send data to the serial
96 	                         // port when DTR is on
97 
98 	bool transparent = false; // if true, don't send 0xff 0xXX to toggle
99 	                          // DSR/CTS.
100 
101 	bool telnet = false; // Do Telnet parsing.
102 
103     // Telnet's brain
104 #define TEL_CLIENT 0
105 #define TEL_SERVER 1
106 
107 	SocketState TelnetEmulation(const uint8_t data);
108 
109 	// Telnet's memory
110 	struct {
111 		bool binary[2] = {false};
112 		bool echo[2] = {false};
113 		bool supressGA[2] = {false};
114 		bool timingMark[2] = {false};
115 
116 		bool inIAC = false;
117 		bool recCommand = false;
118 		uint8_t command = 0;
119 	} telClient;
120 };
121 
122 #endif	// C_MODEM
123 #endif	// include guard
124