lockstep.cpp

Go to the documentation of this file.
00001 /* ES40 emulator.
00002  * Copyright (C) 2007 by Camiel Vanderhoeven
00003  *
00004  * Website: www.camicom.com
00005  * E-mail : camiel@camicom.com
00006  * 
00007  * This program is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU General Public License
00009  * as published by the Free Software Foundation; either version 2
00010  * of the License, or (at your option) any later version.
00011  * 
00012  * This program is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this program; if not, write to the Free Software
00019  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00020  * 
00021  * Although this is not required, the author would appreciate being notified of, 
00022  * and receiving any modifications you may make to the source code that might serve
00023  * the general public.
00024  */
00025 
00044 #include "StdAfx.h"
00045 
00046 #include "lockstep.h"
00047 
00048 #if defined(IDB) && (defined(LS_MASTER) || defined(LS_SLAVE))
00049 int   ls_Socket;
00050 
00051 #if defined(LS_MASTER)
00052 char  ls_IP[30];
00053 #else
00054 int   ls_listenSocket;
00055 #endif
00056 void lockstep_init()
00057 {
00058   struct sockaddr_in  Address;
00059 
00060 #if defined(_WIN32)
00061 
00062   // Windows Sockets only work after calling WSAStartup.
00063   WSADATA wsa;
00064   WSAStartup(0x0101, &wsa);
00065 #endif // defined (_WIN32)
00066 #if defined(LS_MASTER)
00067   int result = -1;
00068   printf("Please enter the IP address of the lockstep slave to connect to: ");
00069   scanf("%s", ls_IP);
00070 
00071   ls_Socket = socket(AF_INET, SOCK_STREAM, 0);
00072 
00073   Address.sin_family = AF_INET;
00074   Address.sin_port = htons(21260);
00075   Address.sin_addr.s_addr = inet_addr(ls_IP);
00076 
00077   printf("%%LST-I-WAIT: Waiting to initiate lockstep connection to %s.\n", ls_IP);
00078 
00079   while(result == -1)
00080     result = connect(ls_Socket, (struct sockaddr*) &Address,
00081                      sizeof(struct sockaddr));
00082 
00083 #else // defined(LS_MASTER)
00084   socklen_t nAddressSize = sizeof(struct sockaddr_in);
00085 
00086   ls_listenSocket = socket(AF_INET, SOCK_STREAM, 0);
00087   if(ls_listenSocket == INVALID_SOCKET)
00088     printf("%%LST-F-NOSOCK Could not open lockstep socket to listen on!\n");
00089 
00090   Address.sin_addr.s_addr = INADDR_ANY;
00091   Address.sin_port = htons(21260);
00092   Address.sin_family = AF_INET;
00093 
00094   int optval = 1;
00095   setsockopt(ls_listenSocket, SOL_SOCKET, SO_REUSEADDR, (char*) &optval,
00096              sizeof(optval));
00097   bind(ls_listenSocket, (struct sockaddr*) &Address, sizeof(Address));
00098   listen(ls_listenSocket, 1);
00099 
00100   printf("%%LST-I-WAIT: Waiting for lockstep connection on port %d.\n", 21260);
00101 
00102   //  Wait until we have a connection
00103   ls_Socket = INVALID_SOCKET;
00104   while(ls_Socket == INVALID_SOCKET)
00105     ls_Socket = accept(ls_listenSocket, (struct sockaddr*) &Address,
00106                        &nAddressSize);
00107 #endif
00108   printf("%%LST-I-INIT: Lock-step connection initialized.\n");
00109 }
00110 
00111 void lockstep_sync_m2s(char* s)
00112 {
00113 #if defined(LS_MASTER)
00114   send(ls_Socket, s, strlen(s) + 1, 0);
00115 
00116 #else
00117   fd_set          readset;
00118   unsigned char   buffer[1000];
00119   ssize_t         size;
00120   struct timeval  tv;
00121 
00122   buffer[0] = 0;
00123 
00124   while(strcmp((char*) buffer, s))
00125   {
00126     FD_ZERO(&readset);
00127     FD_SET(ls_Socket, &readset);
00128     tv.tv_sec = 30;
00129     tv.tv_usec = 0;
00130     while(select(ls_Socket + 1, &readset, NULL, NULL, &tv) <= 0);
00131     size = recv(ls_Socket, (char*) buffer, 999, 0);
00132     buffer[size + 1] = 0;   // force null termination.
00133   }
00134 #endif
00135 }
00136 
00137 void lockstep_sync_s2m(char* s)
00138 {
00139 #if defined(LS_SLAVE)
00140   send(ls_Socket, s, strlen(s) + 1, 0);
00141 
00142 #else
00143   fd_set          readset;
00144   unsigned char   buffer[1000];
00145   ssize_t         size;
00146   struct timeval  tv;
00147 
00148   buffer[0] = 0;
00149 
00150   while(strcmp((char*) buffer, s))
00151   {
00152     FD_ZERO(&readset);
00153     FD_SET(ls_Socket, &readset);
00154     tv.tv_sec = 30;
00155     tv.tv_usec = 0;
00156     while(select(ls_Socket + 1, &readset, NULL, NULL, &tv) <= 0);
00157     size = recv(ls_Socket, (char*) buffer, 999, 0);
00158     buffer[size + 1] = 0;   // force null termination.
00159   }
00160 #endif
00161 }
00162 
00163 char  cmpbuffer[10000];
00164 
00165 void lockstep_compare(char* s)
00166 {
00167 #if defined(LS_SLAVE)
00168   send(ls_Socket, s, strlen(s) + 1, 0);
00169 
00170 #else
00171   fd_set          readset;
00172   ssize_t         size;
00173   struct timeval  tv;
00174   char*           b1;
00175   char*           b2;
00176   char*           n1;
00177   char*           n2;
00178 
00179   FD_ZERO(&readset);
00180   FD_SET(ls_Socket, &readset);
00181   tv.tv_sec = 30;
00182   tv.tv_usec = 0;
00183   while(select(ls_Socket + 1, &readset, NULL, NULL, &tv) <= 0);
00184   size = recv(ls_Socket, cmpbuffer, 99999, 0);
00185   cmpbuffer[size + 1] = 0;  // force null termination.
00186 
00187   //  printf("Comparing <%s> AND <%s>\n",s,buffer);
00188   b1 = s;
00189   b2 = cmpbuffer;
00190 
00191   while(b1 && b2)
00192   {
00193     n1 = strchr(b1, '\n');
00194     n2 = strchr(b2, '\n');
00195     if(n1)
00196       *n1++ = '\0';
00197     if(n2)
00198       *n2++ = '\0';
00199     if(strcmp(b1, b2))
00200     {
00201       printf("*************** LOCKSTEP: DIFFERENCE ENCOUNTERED ***************\n");
00202       printf(" local system: %s\n", b1);
00203       printf("remote system: %s\n", b2);
00204       printf("***************     PRESS ENTER TO CONTINUE      ***************\n");
00205       getc(stdin);
00206     }
00207 
00208     b1 = n1;
00209     b2 = n2;
00210   }
00211 #endif
00212 }
00213 
00214 void lockstep_send(char* s)
00215 {
00216 
00217   //  printf("<send %s>",s);
00218   fd_set          readset;
00219   ssize_t         size;
00220   struct timeval  tv;
00221 
00222   char            sConf[100] = "";
00223   while(strcmp(sConf, "ACK"))
00224   {
00225     send(ls_Socket, s, strlen(s) + 1, 0);
00226     FD_ZERO(&readset);
00227     FD_SET(ls_Socket, &readset);
00228     tv.tv_sec = 5;
00229     tv.tv_usec = 0;
00230     if(select(ls_Socket + 1, &readset, NULL, NULL, &tv) > 0)
00231     {
00232       size = recv(ls_Socket, sConf, 99, 0);
00233       sConf[size + 1] = 0;  // force null termination.
00234     }
00235   }
00236 }
00237 
00238 void lockstep_receive(char* s, int sz)
00239 {
00240   fd_set          readset;
00241   ssize_t         size = 0;
00242   struct timeval  tv;
00243   s[0] = 'R';
00244 
00245   while(!size)
00246   {
00247     FD_ZERO(&readset);
00248     FD_SET(ls_Socket, &readset);
00249     tv.tv_sec = 30;
00250     tv.tv_usec = 0;
00251     if(select(ls_Socket + 1, &readset, NULL, NULL, &tv) > 0)
00252     {
00253       size = recv(ls_Socket, s, sz - 1, 0);
00254       s[size + 1] = 0;      // force null termination.
00255     }
00256   }
00257 
00258   send(ls_Socket, "ACK", 4, 0);
00259 }
00260 #endif // defined(IDB) && (defined(LS_MASTER) || defined(LS_SLAVE))

SourceForge.net Logo
Project space on SourceForge.net