DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/serialport/softmodem.h
00001 /*
00002  *  Copyright (C) 2002-2013  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
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 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,ResERROR,
00046         ResCONNECT,ResRING,
00047         ResBUSY,ResNODIALTONE,ResNOCARRIER
00048 };
00049 
00050 #define TEL_CLIENT 0
00051 #define TEL_SERVER 1
00052 
00053 class CFifo {
00054 public:
00055         CFifo(Bitu _size) {
00056                 size=_size;
00057                 pos=used=0;
00058                 data=new Bit8u[size];
00059         }
00060         ~CFifo() {
00061                 delete[] data;
00062         }
00063         INLINE Bitu left(void) {
00064                 return size-used;
00065         }
00066         INLINE Bitu inuse(void) {
00067                 return used;
00068         }
00069         void clear(void) {
00070                 used=pos=0;
00071         }
00072 
00073         void addb(Bit8u _val) {
00074                 if(used>=size) {
00075                         static Bits lcount=0;
00076                         if (lcount<1000) {
00077                                 lcount++;
00078                                 LOG_MSG("MODEM: FIFO Overflow! (addb)");
00079                         }
00080                         return;
00081                 }
00082                 //assert(used<size);
00083                 Bitu where=pos+used;
00084                 if (where>=size) where-=size;
00085                 data[where]=_val;
00086                 //LOG_MSG("+%x",_val);
00087                 used++;
00088         }
00089         void adds(Bit8u * _str,Bitu _len) {
00090                 if((used+_len)>size) {
00091                         static Bits lcount=0;
00092                         if (lcount<1000) {
00093                                 lcount++;
00094                                 LOG_MSG("MODEM: FIFO Overflow! (adds len %u)",(int)_len);
00095                         }
00096                         return;
00097                 }
00098                 
00099                 //assert((used+_len)<=size);
00100                 Bitu where=pos+used;
00101                 used+=_len;
00102                 while (_len--) {
00103                         if (where>=size) where-=size;
00104                         //LOG_MSG("+'%x'",*_str);
00105                         data[where++]=*_str++;
00106                 }
00107         }
00108         Bit8u getb(void) {
00109                 if (!used) {
00110                         static Bits lcount=0;
00111                         if (lcount<1000) {
00112                                 lcount++;
00113                                 LOG_MSG("MODEM: FIFO UNDERFLOW! (getb)");
00114                         }
00115                         return data[pos];
00116                 }
00117                         Bitu where=pos;
00118                 if (++pos>=size) pos-=size;
00119                 used--;
00120                 //LOG_MSG("-%x",data[where]);
00121                 return data[where];
00122         }
00123         void gets(Bit8u * _str,Bitu _len) {
00124                 if (!used) {
00125                         static Bits lcount=0;
00126                         if (lcount<1000) {
00127                                 lcount++;
00128                                 LOG_MSG("MODEM: FIFO UNDERFLOW! (gets len %d)",(int)_len);
00129                         }
00130                         return;
00131                 }
00132                         //assert(used>=_len);
00133                 used-=_len;
00134                 while (_len--) {
00135                         //LOG_MSG("-%x",data[pos]);
00136                         *_str++=data[pos];
00137                         if (++pos>=size) pos-=size;
00138                 }
00139         }
00140 private:
00141         Bit8u * data;
00142         Bitu size,pos,used;
00143 };
00144 #define MREG_AUTOANSWER_COUNT 0
00145 #define MREG_RING_COUNT 1
00146 #define MREG_ESCAPE_CHAR 2
00147 #define MREG_CR_CHAR 3
00148 #define MREG_LF_CHAR 4
00149 #define MREG_BACKSPACE_CHAR 5
00150 
00151 
00152 class CSerialModem : public CSerial {
00153 public:
00154 
00155         CFifo *rqueue;
00156         CFifo *tqueue;
00157 
00158         CSerialModem(Bitu id, CommandLine* cmd);
00159         ~CSerialModem();
00160 
00161         void Reset();
00162 
00163         void SendLine(const char *line);
00164         void SendRes(ResTypes response);
00165         void SendNumber(Bitu val);
00166 
00167         void EnterIdleState();
00168         void EnterConnectedState();
00169 
00170         void openConnection(void);
00171         bool Dial(char * host);
00172         void AcceptIncomingCall(void);
00173         Bitu ScanNumber(char * & scan);
00174         char GetChar(char * & scan);
00175 
00176         void DoCommand();
00177         
00178         void MC_Changed(Bitu new_mc);
00179 
00180         void TelnetEmulation(Bit8u * data, Bitu size);
00181 
00182         //TODO
00183         void Timer2(void);
00184         void handleUpperEvent(Bit16u type);
00185 
00186         void RXBufferEmpty();
00187 
00188         void transmitByte(Bit8u val, bool first);
00189         void updatePortConfig(Bit16u divider, Bit8u lcr);
00190         void updateMSR();
00191 
00192         void setBreak(bool);
00193 
00194         void setRTSDTR(bool rts, bool dtr);
00195         void setRTS(bool val);
00196         void setDTR(bool val);
00197 
00198 protected:
00199         char cmdbuf[255];
00200         bool commandmode;               // true: interpret input as commands
00201         bool echo;                              // local echo on or off
00202 
00203         bool oldDTRstate;
00204         bool ringing;
00205         //bool response;
00206         bool numericresponse;   // true: send control response as number.
00207                                                         // false: send text (i.e. NO DIALTONE)
00208         bool telnetmode;                // true: process IAC commands.
00209         
00210         bool connected;
00211         Bitu doresponse;
00212 
00213         Bit8u waiting_tx_character;
00214 
00215         Bitu cmdpause;
00216         Bits ringtimer;
00217         Bits ringcount;
00218         Bitu plusinc;
00219         Bitu cmdpos;
00220         Bitu flowcontrol;
00221 
00222         Bit8u tmpbuf[MODEM_BUFFER_QUEUE_SIZE];
00223 
00224         Bitu listenport;
00225         Bit8u reg[SREGS];
00226         
00227         
00228         TCPServerSocket* serversocket;
00229         TCPClientSocket* clientsocket;
00230         TCPClientSocket* waitingclientsocket;
00231 
00232         struct {
00233                 bool binary[2];
00234                 bool echo[2];
00235                 bool supressGA[2];
00236                 bool timingMark[2];
00237                                         
00238                 bool inIAC;
00239                 bool recCommand;
00240                 Bit8u command;
00241         } telClient;
00242         struct {
00243                 bool active;
00244                 double f1, f2;
00245                 Bitu len,pos;
00246                 char str[256];
00247         } dial;
00248 };
00249 #endif
00250 #endif