DOSBox-X
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
src/hardware/serialport/misc_util.cpp
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 /* $Id $ */
00020 
00021 
00022 #include "config.h"
00023 
00024 #if C_MODEM
00025 
00026 /*****************************************************************************/
00027 // C++ SDLnet wrapper
00028 
00029 #include "misc_util.h"
00030 
00031 struct _TCPsocketX {
00032         int ready;
00033 #ifdef NATIVESOCKETS
00034         SOCKET channel;
00035 #endif
00036         IPaddress remoteAddress;
00037         IPaddress localAddress;
00038         int sflag;
00039 };
00040 
00041 Bit32u Netwrapper_GetCapabilities()
00042 {
00043         Bit32u retval=0;
00044         retval = CAPWORD;
00045         return retval;
00046 }
00047 
00048 #ifdef NATIVESOCKETS
00049 TCPClientSocket::TCPClientSocket(int platformsocket) {
00050         sendbuffer=0;
00051         nativetcpstruct = new Bit8u[sizeof(struct _TCPsocketX)];
00052         
00053         mysock = (TCPsocket)nativetcpstruct;
00054         isopen = false;
00055         if(!SDLNetInited) {
00056         if(SDLNet_Init()==-1) {
00057                         LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError());
00058                         return;
00059                 }
00060                 SDLNetInited = true;
00061         }
00062         // fill the SDL socket manually
00063         ((struct _TCPsocketX*)nativetcpstruct)->ready=0;
00064         ((struct _TCPsocketX*)nativetcpstruct)->sflag=0;
00065         ((struct _TCPsocketX*)nativetcpstruct)->channel=(SOCKET) platformsocket;
00066         sockaddr_in             sa;
00067 #ifdef OS2
00068         int                     sz;
00069 #else
00070         socklen_t               sz;
00071 #endif
00072         sz=sizeof(sa);
00073         if(getpeername(platformsocket, (sockaddr *)(&sa), &sz)==0) {
00074                 ((struct _TCPsocketX*)nativetcpstruct)->
00075                         remoteAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//);
00076                 ((struct _TCPsocketX*)nativetcpstruct)->
00077                         remoteAddress.port=/*ntohs(*/sa.sin_port;//);
00078         }
00079         else {
00080                 mysock=0;
00081                 return;
00082         }
00083         sz=sizeof(sa);
00084         if(getsockname(platformsocket, (sockaddr *)(&sa), &sz)==0) {
00085                 ((struct _TCPsocketX*)nativetcpstruct)->
00086                         localAddress.host=/*ntohl(*/sa.sin_addr.s_addr;//);
00087                 ((struct _TCPsocketX*)nativetcpstruct)->
00088                         localAddress.port=/*ntohs(*/sa.sin_port;//);
00089         }
00090         else {
00091                 mysock=0;
00092                 return;
00093         }
00094         if(mysock!=0) {
00095                 listensocketset = SDLNet_AllocSocketSet(1);
00096                 if(!listensocketset) return;
00097                 SDLNet_TCP_AddSocket(listensocketset, mysock);
00098                 isopen=true;
00099                 return;
00100         }
00101         mysock=0;
00102         return;
00103 }
00104 #endif // NATIVESOCKETS
00105 
00106 TCPClientSocket::TCPClientSocket(TCPsocket source) {
00107 #ifdef NATIVESOCKETS
00108         nativetcpstruct=0;
00109 #endif
00110         sendbuffer=0;
00111         isopen = false;
00112         if(!SDLNetInited) {
00113         if(SDLNet_Init()==-1) {
00114                         LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError());
00115                         return;
00116                 }
00117                 SDLNetInited = true;
00118         }       
00119         
00120         mysock=0;
00121         listensocketset=0;
00122         if(source!=0) {
00123                 mysock = source;
00124                 listensocketset = SDLNet_AllocSocketSet(1);
00125                 if(!listensocketset) return;
00126                 SDLNet_TCP_AddSocket(listensocketset, source);
00127 
00128                 isopen=true;
00129         }
00130 }
00131 TCPClientSocket::TCPClientSocket(const char* destination, Bit16u port) {
00132 #ifdef NATIVESOCKETS
00133         nativetcpstruct=0;
00134 #endif
00135         sendbuffer=0;
00136         isopen = false;
00137         if(!SDLNetInited) {
00138         if(SDLNet_Init()==-1) {
00139                         LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError());
00140                         return;
00141                 }
00142                 SDLNetInited = true;
00143         }       
00144         mysock=0;
00145         listensocketset=0;
00146         
00147         IPaddress openip;
00148         //Ancient versions of SDL_net had this as char*. People still appear to be using this one.
00149         if (!SDLNet_ResolveHost(&openip,const_cast<char*>(destination),port)) {
00150                 listensocketset = SDLNet_AllocSocketSet(1);
00151                 if(!listensocketset) return;
00152                 mysock = SDLNet_TCP_Open(&openip);
00153                 if(!mysock) return;
00154                 SDLNet_TCP_AddSocket(listensocketset, mysock);
00155                 isopen=true;
00156         }
00157 }
00158 
00159 TCPClientSocket::~TCPClientSocket() {
00160         
00161         if(sendbuffer) delete [] sendbuffer;
00162 #ifdef NATIVESOCKETS
00163         if(nativetcpstruct) delete [] nativetcpstruct;
00164         else
00165 #endif
00166         if(mysock) {
00167                 if(listensocketset) SDLNet_TCP_DelSocket(listensocketset,mysock);
00168                 SDLNet_TCP_Close(mysock);
00169         }
00170 
00171         if(listensocketset) SDLNet_FreeSocketSet(listensocketset);
00172 }
00173 bool TCPClientSocket::GetRemoteAddressString(Bit8u* buffer) {
00174         IPaddress* remote_ip;
00175         Bit8u b1, b2, b3, b4;
00176         remote_ip=SDLNet_TCP_GetPeerAddress(mysock);
00177         if(!remote_ip) return false;
00178         b4=remote_ip->host>>24;
00179         b3=(remote_ip->host>>16)&0xff;
00180         b2=(remote_ip->host>>8)&0xff;
00181         b1=remote_ip->host&0xff;
00182         sprintf((char*)buffer,"%u.%u.%u.%u",b1,b2,b3,b4);
00183         return true;
00184 }
00185 
00186 bool TCPClientSocket::ReceiveArray(Bit8u* data, Bitu* size) {
00187         if(SDLNet_CheckSockets(listensocketset,0))
00188         {
00189                 Bits retval = SDLNet_TCP_Recv(mysock, data, (int)(*size));
00190                 if(retval<1) {
00191                         isopen=false;
00192                         *size=0;
00193                         return false;
00194                 } else {
00195                         *size=(Bitu)retval;
00196                         return true;
00197                 }
00198         }
00199         else {
00200                 *size=0;
00201                 return true;
00202         }
00203 }
00204 
00205 
00206 Bits TCPClientSocket::GetcharNonBlock() {
00207 // return:
00208 // -1: no data
00209 // -2: socket closed
00210 // 0..255: data
00211         if(SDLNet_CheckSockets(listensocketset,0))
00212         {
00213                 Bitu retval =0;
00214                 if(SDLNet_TCP_Recv(mysock, &retval, 1)!=1) {
00215                         isopen=false;
00216                         return -2;
00217                 } else return (Bits)retval;
00218         }
00219         else return -1;
00220 }
00221 bool TCPClientSocket::Putchar(Bit8u data) {
00222         if(SDLNet_TCP_Send(mysock, &data, 1)!=1) {
00223                 isopen=false;
00224                 return false;
00225         }
00226         return true;
00227 }
00228 
00229 bool TCPClientSocket::SendArray(Bit8u* data, Bitu bufsize) {
00230         if((Bitu)SDLNet_TCP_Send(mysock, data, (int)bufsize) != bufsize) {
00231                 isopen=false;
00232                 return false;
00233         }
00234         return true;
00235 }
00236 
00237 bool TCPClientSocket::SendByteBuffered(Bit8u data) {
00238         
00239         if(sendbufferindex==(sendbuffersize-1)) {
00240                 // buffer is full, get rid of it
00241                 sendbuffer[sendbufferindex]=data;
00242                 sendbufferindex=0;
00243                 
00244                 if((Bitu)SDLNet_TCP_Send(mysock, sendbuffer, (int)sendbuffersize) != sendbuffersize) {
00245                         isopen=false;
00246                         return false;
00247                 }
00248         } else {
00249                 sendbuffer[sendbufferindex]=data;
00250                 sendbufferindex++;
00251         }
00252         return true;
00253 }
00254 /*
00255 bool TCPClientSocket::SendArrayBuffered(Bit8u* data, Bitu bufsize) {
00256         
00257         Bitu bytes
00258         while(
00259         
00260         // first case, buffer already full
00261         if(sendbufferindex==(sendbuffersize-1)) {
00262                 // buffer is full, get rid of it
00263                 sendbuffer[sendbufferindex]=data;
00264                 sendbufferindex=0;
00265                 
00266                 if(SDLNet_TCP_Send(mysock, sendbuffer, sendbuffersize)!=sendbuffersize) {
00267                         isopen=false;
00268                         return false;
00269                 }
00270         }
00271 }
00272 */
00273 void TCPClientSocket::FlushBuffer() {
00274         if(sendbufferindex) {
00275                 if((Bitu)SDLNet_TCP_Send(mysock, sendbuffer,
00276                         (int)sendbufferindex) != sendbufferindex) {
00277                         isopen=false;
00278                         return;
00279                 }
00280                 sendbufferindex=0;
00281         }
00282 }
00283 
00284 void TCPClientSocket::SetSendBufferSize(Bitu bufsize) {
00285         if(sendbuffer) delete [] sendbuffer;
00286         sendbuffer = new Bit8u[bufsize];
00287         sendbuffersize=bufsize;
00288         sendbufferindex=0;
00289 }
00290 
00291 
00292 TCPServerSocket::TCPServerSocket(Bit16u port)
00293 {
00294         isopen = false;
00295         mysock = 0;
00296         if(!SDLNetInited) {
00297         if(SDLNet_Init()==-1) {
00298                         LOG_MSG("SDLNet_Init failed: %s\n", SDLNet_GetError());
00299                         return;
00300                 }
00301                 SDLNetInited = true;
00302         }
00303         if (port) {
00304                 IPaddress listen_ip;
00305                 SDLNet_ResolveHost(&listen_ip, NULL, port);
00306                 mysock=SDLNet_TCP_Open(&listen_ip);
00307                 if(!mysock) return;
00308         }
00309         else return;
00310         isopen = true;
00311 }
00312 
00313 TCPServerSocket::~TCPServerSocket() {
00314         if(mysock) SDLNet_TCP_Close(mysock);
00315 }
00316 
00317 TCPClientSocket* TCPServerSocket::Accept() {
00318 
00319         TCPsocket new_tcpsock;
00320 
00321         new_tcpsock=SDLNet_TCP_Accept(mysock);
00322         if(!new_tcpsock) {
00323                 //printf("SDLNet_TCP_Accept: %s\n", SDLNet_GetError());
00324                 return 0;
00325         }
00326         
00327         return new TCPClientSocket(new_tcpsock);
00328 }
00329 #endif // #if C_MODEM