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