DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/serialport/softmodem.h
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