00001 /******************************************************************** 00002 Description: The CoreClass Methods 00003 part of the 3Dsia project 00004 created: xandi, 080400 00005 00006 History: 00007 date, name, changes, in funtion 00008 180400 StonedBones added dynamic packet length 00009 00010 ********************************************************************/ 00011 00012 00013 #include "misc.h" 00014 00015 #include <pthread.h> 00016 00017 #include <arpa/inet.h> 00018 #include <sys/socket.h> 00019 00020 #include "../common/communication.h" 00021 00022 #include "../common/buffer.h" 00023 #include "../common/protocol.h" 00024 #include "../common/options.h" 00025 #include "../common/config.h" 00026 #include "../common/matrixThread.h" 00027 00028 #include "coreClass.h" 00029 #include "quartz.h" 00030 00031 00032 /*................................................................... 00033 Description: This constructor does paramter-parsing 00034 Args: ThreadArgs* targs 00035 Returns: 00036 Created: xandi, 080400 00037 ToDo: 00038 a real parameter-parsing, providing switches like 00039 -s servername 00040 -l username 00041 -p password 00042 -a serveraddress 00043 -P port 00044 -.... 00045 00046 Comments: 00047 this method should of course become a bit more flexible 00048 00049 Changes: 00050 -------------------------------------------------------------------*/ 00051 00052 coreClass::coreClass ( ThreadArgs* targs ) 00053 { 00054 fprintf(stderr,"[cC.constructor] parsing %d parameters\n",targs->argc); 00055 mySocket = 0; 00056 serverPort = 0; 00057 qObj = 0; 00058 coreIn = 0; 00059 coreOut = 0; 00060 00061 if ( targs->argc >= 4 ) 00062 { 00063 username = targs->argv[1]; 00064 password = targs->argv[2]; 00065 serverAddress = targs->argv[3]; 00066 00067 fprintf(stderr,"\nUsername: %s", username.c_str() ); 00068 fprintf(stderr,"\tPassword: %s\n", password.c_str()); 00069 fprintf(stderr,"Serveraddress: %s\n",serverAddress.c_str() ); 00070 00071 if ( targs->argc >= 5 ) 00072 { 00073 fprintf(stderr,"Too many arguments - *snip* :)\n"); 00074 } 00075 } 00076 else 00077 { 00078 username = "clonewar"; 00079 password = "idpman"; 00080 serverAddress = DEFAULT_HOST; 00081 } 00082 00083 serverPort = DEFAULT_PORT; 00084 } 00085 00086 00087 /*................................................................... 00088 Description: This constructor reads from the configuration file everything it knows about [servername] 00089 Args: none 00090 Returns: none 00091 Created: 10.4.2000, StonedBones 00092 [ToDo:] 00093 [Comments:] 00094 Changes: 00095 -------------------------------------------------------------------*/ 00096 00097 coreClass::coreClass () { 00098 mySocket = 0; 00099 serverPort = 0; 00100 qObj = 0; 00101 coreIn = 0; 00102 coreOut = 0; 00103 00104 Config* tmpConfig = new Config (); 00105 00106 tmpConfig->openConfig (CLIENT_CONFIG_FILE); 00107 00108 if (tmpConfig->searchTag ("User")) { 00109 username = tmpConfig->getCharVariable ("Name"); 00110 password = tmpConfig->getCharVariable ("Password"); 00111 }; 00112 if (tmpConfig->searchTag ("DefaultServer")) { 00113 serverAddress = tmpConfig->getCharVariable ("Adress"); 00114 serverPort = tmpConfig->getIntVariable ("Port"); 00115 }; 00116 00117 if (username == "") username = "clonewar"; 00118 if (password == "") password = "idpman"; 00119 if (serverAddress == "") serverAddress = DEFAULT_HOST; 00120 if (serverPort == -111) serverPort = DEFAULT_PORT; 00121 }; 00122 00123 00124 00125 /*................................................................... 00126 Description: connect - connect to server 00127 Args: void 00128 Returns: 00129 0 succeeded 00130 1 didn't succeeded 00131 00132 Created: xandi, 080400 00133 [ToDo:] 00134 [Comments:] 00135 Changes: 00136 -------------------------------------------------------------------*/ 00137 00138 bool coreClass::connectNow ( void ) 00139 { 00140 fprintf(stderr,"[cC.connectNow] \n"); 00141 00142 ComArgs inArgs; 00143 ComArgs outArgs; 00144 00145 inArgs.buffer = coreIn = new Buffer ( ); 00146 outArgs.buffer = coreOut = new Buffer ( ); 00147 00148 bool check = connectTo ( serverAddress ); 00149 00150 inArgs.socket = mySocket; 00151 outArgs.socket = mySocket; 00152 00153 check = pthread_create ( &incomingThread, NULL, IncomingThread, &inArgs ); 00154 check += pthread_create ( &outgoingThread, NULL, OutgoingThread, &outArgs ); 00155 00156 check += handshake ( ); 00157 check += authenticate ( ); 00158 00159 return check; 00160 } 00161 00162 00163 /*................................................................... 00164 Description: disconnect - disconnect to server 00165 Args: void 00166 Returns: 00167 0 succeeded 00168 1 didn't succeeded 00169 00170 Created: xandi, 080400 00171 [ToDo:] 00172 [Comments:] 00173 Changes: 00174 -------------------------------------------------------------------*/ 00175 00176 bool coreClass::disconnectNow ( void ) 00177 { 00178 fprintf(stderr,"Nooo, i don't let you, hahahaa!!\n"); 00179 return 0; 00180 } 00181 00182 00183 /*................................................................... 00184 Description: connects to a server 00185 Args: char* dotsandnumbers: TCP/IP adress ("127.0.0.1" rather than "localhost"); 00186 Returns: true on success 00187 Created: StonedBones, ??.2.2000 00188 ToDo: 00189 080400, support for DNS 00190 [Comments:] 00191 Changes: 00192 put from communication into coreClass, 00193 changed it so that it works with coreClass, 080400, xandi 00194 -------------------------------------------------------------------*/ 00195 00196 bool coreClass::connectTo ( string dotsandnumbers ) 00197 { 00198 struct sockaddr_in address; 00199 // struct hostent* host; 00200 00201 fprintf(stderr,"[cC.connectTo] \n"); 00202 address.sin_addr.s_addr = inet_addr (dotsandnumbers.c_str ()); 00203 bzero ( & ( address.sin_zero ), 8 ); 00204 00205 00206 /* 00207 host = gethostbyname ( hostname ); 00208 if (!host) 00209 return false; 00210 }; */ 00211 00212 if ((mySocket = socket (PF_INET, SOCK_STREAM, 0)) < 0) { 00213 return false; 00214 }; 00215 00216 address.sin_family = AF_INET; 00217 address.sin_port = htons (serverPort); 00218 00219 if (connect (mySocket, (sockaddr *) &address, sizeof (address))) { 00220 return false; 00221 }; 00222 00223 return true; 00224 }; 00225 00226 00227 /*................................................................... 00228 Description: handshakes with server 00229 Args: <none> 00230 Returns: true on success 00231 Created: StonedBones, ??.2.2000 00232 [ToDo:] 00233 [Comments:] 00234 Changes: 00235 changed so it works with the new threadsystem, xandi, 080400 00236 cleaned up a bit.. xandi, 090400 00237 -------------------------------------------------------------------*/ 00238 00239 bool coreClass::handshake () 00240 { 00241 packet* pak = new packet; 00242 bool check = false; 00243 00244 fprintf(stderr,"[cC.handshake] \n"); 00245 00246 pak->h.header[0] = PROT_HANDSHAKE; 00247 pak->h.header[1] = HANDSHAKE_GREETING; 00248 pak->h.header[2] = VERSION_MAJOR; 00249 pak->h.header[3] = VERSION_MINOR; 00250 pak->h.header[4] = PATCH_LEVEL; 00251 00252 pak->data = "MATRIX?"; 00253 00254 coreOut->write ( pak ); 00255 00256 while ( coreIn->isEmpty () ); 00257 00258 pak = coreIn->read (); 00259 00260 check = ( ( pak->h.header[0] != PROT_HANDSHAKE ) || ( pak->h.header[1] != HANDSHAKE_GREETING ) ); 00261 check += ( ( pak->h.header[2] > VERSION_MAJOR ) || ( pak->h.header[3] > VERSION_MINOR ) ); 00262 00263 if (!check) fprintf(stderr,"[cC.handshake] successful!\n"); 00264 00265 delete pak; 00266 return check; 00267 } 00268 00269 00270 /*................................................................... 00271 Description: authenticates with name and password 00272 Args: char* name: username; char* passwd: password 00273 Returns: true on success 00274 Created: StonedBones, ??.2.2000 00275 [ToDo:] 00276 [Comments:] 00277 Changes: 00278 changed it to work with new threadsystem, 00279 cleaned up a bit.. 090400, xandi 00280 -------------------------------------------------------------------*/ 00281 00282 //#ifdef AUTHPASSWORD //what was that good for again? 00283 00284 bool coreClass::authenticate ( void ) 00285 { 00286 packet* pak = new packet; 00287 bool check = false; 00288 00289 fprintf (stderr, "[auth.debug] trying authentication using %s and %s...\n",username.c_str(),password.c_str()); 00290 00291 pak->h.header[0] = PROT_AUTHENTICATE; 00292 pak->h.header[1] = AUTH_PASSWORD; 00293 pak->h.header[2] = strlen (username.c_str()); 00294 pak->h.header[3] = strlen (password.c_str()); 00295 00296 pak->data = username; 00297 pak->data+= password; 00298 00299 coreOut->write ( pak ); 00300 00301 while ( coreIn->isEmpty () ); 00302 00303 pak = coreIn->read (); 00304 00305 check = ( ( pak->h.header[0] != PROT_AUTHENTICATE) || (pak->h.header[1] != AUTH_PASSWORD ) ); 00306 check += !( pak->data == "Authentication successful !" ); 00307 00308 // qObj = new QuartzClass ( coreOut, PROT_GET_ALL_CHANGED, 25 ); 00309 // check += pthread_create ( &quartzThread, NULL, QuartzThread, qObj ); 00310 00311 delete pak; 00312 return check; 00313 } 00314 00315 //#endif //#ifdef AUTHPASSWORD 00316 00317 00318 Buffer* coreClass::getBuffer ( int whichbuffer ) 00319 { 00320 if ( whichbuffer == INCOMING ) 00321 return coreIn; 00322 if ( whichbuffer == OUTGOING ) 00323 return coreOut; 00324 00325 fprintf(stderr,"[coreClass::getBuffer] you dumb! (sorry, but i had to say that ;)\n"); 00326 return 0; 00327 } 00328 00329 00330 void coreClass::startQuartz ( unsigned int freq ) 00331 { 00332 qObj = new QuartzClass ( coreOut, PROT_GET_ALL_CHANGED, freq ); 00333 if ( pthread_create ( &quartzThread, NULL, QuartzThread, qObj ) ) 00334 { 00335 cerr << "unable to start quartzthread..\n"; 00336 exit(1); 00337 } 00338 } 00339 00340 void coreClass::setUpdateFreq ( unsigned int framesPerSecond ) 00341 { 00342 if ( !framesPerSecond ) 00343 { 00344 fprintf(stderr,"[cc.setUpdateFreq] who would do that??\n"); 00345 exit (1); 00346 } 00347 00348 if ( !qObj) 00349 { 00350 fprintf(stderr,"coreClass::setUpdateFreq - THIS FUNCTION MUST NOT BE CALLED BEFORE THE QUARTZTHREAD IS STARTED!!\n"); 00351 exit(1); 00352 } 00353 qObj->setFrequency ( framesPerSecond ); 00354 fprintf(stderr,"[cc.setUpdateFreq] %d frames per second mean update every %d microseconds\n",framesPerSecond,1000000/framesPerSecond); 00355 } 00356 00357 00358 /* 00359 void coreClass::accessMatrix ( string matrixname ) 00360 { 00361 packet* pak; 00362 pak = new packet; 00363 00364 fprintf (stderr, "[cC.accessMatrix] trying to access a matrix...\n"); 00365 00366 pak->h.header[0] = PROT_MATRIX_STUFF; 00367 pak->h.header[1] = PROT_ACCESS_MATRIX; 00368 00369 pak->data = matrixname; 00370 00371 coreOut->write ( pak ); 00372 00373 fprintf(stderr,"[cC.accessMatrix] completed.....\n"); 00374 } 00375 */ 00376 00377 /* 00378 bool Communication::dummyAddObject ( char* name ) 00379 { 00380 int amount; 00381 packet bufpak; 00382 00383 fprintf (stderr, "trying to add an object %s...\n",name); 00384 amount = sizeof (packet); 00385 00386 bufpak.h.header[0] = PROT_MATRIX_STUFF; 00387 bufpak.h.header[1] = PROT_ADD_OBJECT; 00388 00389 00390 strcpy (bufpak.data, name); 00391 00392 sendData (bufpak); 00393 00394 bufpak = recvData (); 00395 00396 if ((bufpak.h.header[0] != PROT_REQUEST_REPLY)) 00397 { 00398 return false; 00399 } 00400 00401 return true; 00402 } 00403 00404 bool Communication::dummyGetObject ( int number ) 00405 { 00406 int amount; 00407 packet bufpak; 00408 00409 fprintf (stderr, "trying to get an object %d...\n",number); 00410 amount = sizeof (packet); 00411 00412 bufpak.h.header[0] = PROT_MATRIX_STUFF; 00413 bufpak.h.header[1] = PROT_GET_OBJECT; 00414 bufpak.h.header[2] = number; 00415 00416 sendData (bufpak); 00417 00418 bufpak = recvData (); 00419 00420 if ((bufpak.h.header[0] != PROT_REQUEST_REPLY)) 00421 { 00422 return false; 00423 } 00424 00425 return true; 00426 } 00427 00428 */ 00429 00430