DOSBox-X
|
00001 /* 00002 * Copyright (C) 2002-2020 The DOSBox Team 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published by 00006 * the Free Software Foundation; either version 2 of the License, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License along 00015 * with this program; if not, write to the Free Software Foundation, Inc., 00016 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00017 */ 00018 00019 00020 #ifndef DOSBOX_SERIALMODEM_H 00021 #define DOSBOX_SERIALMODEM_H 00022 00023 #include "dosbox.h" 00024 #if C_MODEM 00025 #include "serialport.h" 00026 00027 #include "misc_util.h" 00028 00029 #define MODEMSPD 57600 00030 #define SREGS 100 00031 00032 //If it's too high you overflow terminal clients buffers i think 00033 #define MODEM_BUFFER_QUEUE_SIZE 1024 00034 00035 #define MODEM_DEFAULT_PORT 23 00036 00037 #define MODEM_TX_EVENT SERIAL_BASE_EVENT_COUNT + 1 00038 #define MODEM_RX_POLLING SERIAL_BASE_EVENT_COUNT + 2 00039 #define MODEM_RING_EVENT SERIAL_BASE_EVENT_COUNT + 3 00040 #define SERIAL_MODEM_EVENT_COUNT SERIAL_BASE_EVENT_COUNT+3 00041 00042 00043 enum ResTypes { 00044 ResNONE, 00045 ResOK, 00046 ResERROR, 00047 ResCONNECT, 00048 ResRING, 00049 ResBUSY, 00050 ResNODIALTONE, 00051 ResNOCARRIER, 00052 ResNOANSWER 00053 }; 00054 00055 #define TEL_CLIENT 0 00056 #define TEL_SERVER 1 00057 00058 bool MODEM_ReadPhonebook(const std::string &filename); 00059 00060 class CFifo { 00061 public: 00062 CFifo(Bitu _size) { 00063 size = _size; 00064 pos = used = 0; 00065 data = new Bit8u[size]; 00066 } 00067 ~CFifo() { 00068 delete[] data; 00069 } 00070 INLINE Bitu left(void) { 00071 return size-used; 00072 } 00073 INLINE Bitu inuse(void) { 00074 return used; 00075 } 00076 void clear(void) { 00077 used = pos = 0; 00078 } 00079 00080 void addb(Bit8u _val) { 00081 if(used>=size) { 00082 static Bits lcount=0; 00083 if (lcount < 1000) { 00084 lcount++; 00085 LOG_MSG("MODEM: FIFO Overflow! (addb)"); 00086 } 00087 return; 00088 } 00089 //assert(used < size); 00090 Bitu where = pos + used; 00091 if (where >= size) where -= size; 00092 data[where] = _val; 00093 //LOG_MSG("+%x", _val); 00094 used++; 00095 } 00096 void adds(Bit8u * _str, Bitu _len) { 00097 if((used+_len) > size) { 00098 static Bits lcount=0; 00099 if (lcount < 1000) { 00100 lcount++; 00101 LOG_MSG("MODEM: FIFO Overflow! (adds len %u)", 00102 static_cast<uint32_t>(_len)); 00103 } 00104 return; 00105 } 00106 00107 //assert((used+_len)<=size); 00108 Bitu where=pos+used; 00109 used+=_len; 00110 while (_len--) { 00111 if (where >= size) where -= size; 00112 //LOG_MSG("+'%x'", *_str); 00113 data[where++] = *_str++; 00114 } 00115 } 00116 Bit8u getb(void) { 00117 if (!used) { 00118 static Bits lcount=0; 00119 if (lcount < 1000) { 00120 lcount++; 00121 LOG_MSG("MODEM: FIFO UNDERFLOW! (getb)"); 00122 } 00123 return data[pos]; 00124 } 00125 Bitu where=pos; 00126 if (++pos >= size) pos -= size; 00127 used--; 00128 //LOG_MSG("-%x", data[where]); 00129 return data[where]; 00130 } 00131 void gets(Bit8u * _str,Bitu _len) { 00132 if (!used) { 00133 static Bits lcount=0; 00134 if (lcount < 1000) { 00135 lcount++; 00136 LOG_MSG("MODEM: FIFO UNDERFLOW! (gets len %u)", 00137 static_cast<uint32_t>(_len)); 00138 } 00139 return; 00140 } 00141 //assert(used>=_len); 00142 used-=_len; 00143 while (_len--) { 00144 //LOG_MSG("-%x", data[pos]); 00145 *_str++ = data[pos]; 00146 if (++pos>=size) pos-=size; 00147 } 00148 } 00149 private: 00150 Bit8u *data; 00151 Bitu size, pos, used; 00152 }; 00153 #define MREG_AUTOANSWER_COUNT 0 00154 #define MREG_RING_COUNT 1 00155 #define MREG_ESCAPE_CHAR 2 00156 #define MREG_CR_CHAR 3 00157 #define MREG_LF_CHAR 4 00158 #define MREG_BACKSPACE_CHAR 5 00159 #define MREG_GUARD_TIME 12 00160 #define MREG_DTR_DELAY 25 00161 00162 class CSerialModem : public CSerial { 00163 public: 00164 00165 CFifo *rqueue; 00166 CFifo *tqueue; 00167 00168 CSerialModem(Bitu id, CommandLine* cmd); 00169 ~CSerialModem(); 00170 00171 void Reset(); 00172 00173 void SendLine(const char *line); 00174 void SendRes(ResTypes response); 00175 void SendNumber(Bitu val); 00176 00177 void EnterIdleState(); 00178 void EnterConnectedState(); 00179 00180 void openConnection(void); 00181 bool Dial(const char *host); 00182 void AcceptIncomingCall(void); 00183 Bitu ScanNumber(char *&scan); 00184 char GetChar(char *&scan); 00185 00186 void DoCommand(); 00187 00188 void MC_Changed(Bitu new_mc); 00189 00190 void TelnetEmulation(Bit8u * data, Bitu size); 00191 00192 //TODO 00193 void Timer2(void); 00194 void handleUpperEvent(Bit16u type); 00195 00196 void RXBufferEmpty(); 00197 00198 void transmitByte(Bit8u val, bool first); 00199 void updatePortConfig(Bit16u divider, Bit8u lcr); 00200 void updateMSR(); 00201 00202 void setBreak(bool); 00203 00204 void setRTSDTR(bool rts, bool dtr); 00205 void setRTS(bool val); 00206 void setDTR(bool val); 00207 00208 protected: 00209 char cmdbuf[255]; 00210 bool commandmode; // true: interpret input as commands 00211 bool echo; // local echo on or off 00212 00213 bool oldDTRstate; 00214 bool ringing; 00215 //bool response; 00216 bool numericresponse; // true: send control response as number. 00217 // false: send text (i.e. NO DIALTONE) 00218 bool telnetmode; // true: process IAC commands. 00219 00220 bool connected; 00221 Bitu doresponse; 00222 00223 Bit8u waiting_tx_character; 00224 00225 Bitu cmdpause; 00226 Bits ringtimer; 00227 Bits ringcount; 00228 Bitu plusinc; 00229 Bitu cmdpos; 00230 Bitu flowcontrol; 00231 Bitu dtrmode; 00232 Bits dtrofftimer; 00233 Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE]; 00234 00235 Bitu listenport; 00236 Bit8u reg[SREGS]; 00237 00238 00239 TCPServerSocket* serversocket; 00240 TCPClientSocket* clientsocket; 00241 TCPClientSocket* waitingclientsocket; 00242 00243 struct { 00244 bool binary[2]; 00245 bool echo[2]; 00246 bool supressGA[2]; 00247 bool timingMark[2]; 00248 00249 bool inIAC; 00250 bool recCommand; 00251 Bit8u command; 00252 } telClient; 00253 struct { 00254 bool active; 00255 double f1, f2; 00256 Bitu len,pos; 00257 char str[256]; 00258 } dial; 00259 }; 00260 #endif 00261 #endif