# FederationManagement.cc

Go to the documentation of this file.

    00001 // ----------------------------------------------------------------------------
    00002 // CERTI - HLA RunTime Infrastructure
    00003 // Copyright (C) 2002-2005  ONERA
    00004 //
    00005 // This file is part of CERTI
    00006 //
    00007 // CERTI is free software ; you can redistribute it and/or modify
    00008 // it under the terms of the GNU General Public License as published by
    00009 // the Free Software Foundation ; either version 2 of the License, or
    00010 // (at your option) any later version.
    00011 //
    00012 // CERTI 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
    00020 //
    00021 // $Id: FederationManagement.cc,v 3.69 2008/10/22 14:24:34 jmm Exp $
    00022 // ----------------------------------------------------------------------------
    00023
    00024 #include <config.h>
    00025 #include "FederationManagement.hh"
    00026
    00027 #include "TimeManagement.hh"
    00028 #include "PrettyDebug.hh"
    00029 #include "NM_Classes.hh"
    00030
    00031 #ifdef _WIN32
    00032 #include <windows.h>
    00033 #else
    00034 #include <list>
    00035 #include <cstdio>
    00036 #include <sys/types.h>
    00037 #include <sys/stat.h>
    00038 #include <unistd.h>
    00039 #include <cstdlib>
    00040 #endif
    00041 #include <cassert>
    00042 #include <memory>
    00043
    00044 using std::list ;
    00045 using std::string ;
    00046
    00047 namespace certi {
    00048 namespace rtia {
    00049
    00050 static pdCDebug D("RTIA_FM", "(RTIA FM) ");
    00051 static PrettyDebug G("GENDOC",__FILE__);
    00052
    00053 // ----------------------------------------------------------------------------
    00055   FederationManagement::FederationManagement(Communications *GC, Statistics* newStat)
    00056     : savingState(false), restoringState(false)
    00057 {
    00058     G.Out(pdGendoc,"enter FederationManagement::FederationManagement");
    00059     comm = GC ;
    00060     stat = newStat ;
    00061     tm = NULL ;
    00062
    00063     _numero_federation = 0 ;
    00064     federate = 0 ;
    00065
    00066     _fin_execution = false ;
    00067
    00068     //_est_createur_federation = false ;
    00069     _est_membre_federation = false ;
    00070
    00071     _nom_federation = "";
    00072     _nom_federe     = "";
    00073     //_FEDid          = NULL;is now a string then...
    00074     G.Out(pdGendoc,"exit  FederationManagement::FederationManagement");
    00075 }
    00076
    00077 // ----------------------------------------------------------------------------
    00079 FederationManagement::~FederationManagement()
    00080 {
    00081     TypeException e ;
    00082     G.Out(pdGendoc,"enter ~FederationManagement");
    00083
    00084     if (_est_membre_federation) {
    00085         resignFederationExecution(RTI::DELETE_OBJECTS, e);
    00086     }
    00087
    00088     // BUG: On devrait pouvoir quitter une federation que l'on a cree
    00089     // sans la detruire en partant.
    00090     // a-t-on avertit les autres federes de notre depart et donc
    00091     // de la destruction de notre objet par RemoveObject(HARZI)
    00092     // car le Remove Object ne diffuse pas le message
    00093     //if (_est_createur_federation) {
    00094     //    cout << "RTIA: Staying active to destroy federation..." << endl ;
    00095
    00096      //  destroyFederationExecution(_nom_federation, e);
    00097       // while (e != e_NO_EXCEPTION) {
    00098     //          sleep(1);
    00099           //  destroyFederationExecution(_nom_federation, e);
    00100        // }
    00101         cout << "RTIA: Federate destroyed" << endl ;
    00102     //}
    00103
    00104     //delete[] _FEDid ;
    00105     G.Out(pdGendoc,"exit  ~FederationManagement");
    00106 }
    00107
    00108 // ----------------------------------------------------------------------------
    00110 void
    00111 FederationManagement::
    00112 createFederationExecution(std::string theName,
    00113                           TypeException &e)
    00114          throw ( FederationExecutionAlreadyExists,
    00115                  CouldNotOpenFED,ErrorReadingFED,
    00116                  RTIinternalError)
    00117 {
    00118     NM_Create_Federation_Execution requete;
    00119
    00120     G.Out(pdGendoc,"enter FederationManagement::createFederationExecution");
    00121     D.Out(pdInit, "Creating Federation %s.", theName.c_str());
    00122
    00123     e = e_NO_EXCEPTION ;
    00124
    00125     if (_est_membre_federation)
    00126        {
    00127         std::cout<<"Federate "<<_nom_federe<<" is yet a federation member"<<std::endl;
    00128         e = e_RTIinternalError ;
    00129         }
    00130
    00131     if (e == e_NO_EXCEPTION)
    00132         {
    00133         requete.federationName = theName;
    00134         requete.FEDid = _FEDid;
    00135
    00136         G.Out(pdGendoc,"createFederationExecution====>   send Message to RTIG");
    00137
    00138         comm->sendMessage(&requete);
    00139
    00140         std::auto_ptr<NetworkMessage> reponse(comm->waitMessage(NetworkMessage::CREATE_FEDERATION_EXECUTION,
    00141                           federate));
    00142
    00143         G.Out(pdGendoc,"createFederationExecution<== receive Message from RTIG");
    00144
    00145         // We have to see if C_F_E is OK.
    00146
    00147         if (reponse->exception == e_NO_EXCEPTION)
    00148             {
    00149             _nom_federation = std::string(theName);
    00150             _numero_federation = reponse->federation ;
    00151             D.Out(pdInit, "est createur");
    00152             }
    00153         else if (reponse->exception == e_CouldNotOpenFED)
    00154             // RTIG encounters a problem creating federation execution
    00155             {
    00156             e = reponse->exception;
    00157             G.Out(pdGendoc,"exit FederationManagement::"
    00158                            "createFederationExecution on exception");
    00159             throw CouldNotOpenFED (reponse->exceptionReason.c_str()) ;
    00160             }
    00161         else if (reponse->exception == e_FederationExecutionAlreadyExists)
    00162             {
    00163             e = reponse->exception;
    00164             G.Out(pdGendoc,"exit FederationManagement::"
    00165                            "createFederationExecution on exception");
    00166             throw FederationExecutionAlreadyExists (reponse->exceptionReason.c_str()) ;
    00167             }
    00168         else if (reponse->exception == e_ErrorReadingFED)
    00169             {
    00170             e = reponse->exception;
    00171             G.Out(pdGendoc,"exit FederationManagement::"
    00172                            "createFederationExecution on exception ErrorReadingFED");
    00173             throw ErrorReadingFED (reponse->exceptionReason.c_str()) ;
    00174             }
    00175         else
    00176             {
    00177             e = reponse->exception ;
    00178             G.Out(pdGendoc,"exit FederationManagement::"
    00179                            "createFederationExecution on exception RTIinternalError");
    00180             throw RTIinternalError (reponse->exceptionReason.c_str()) ;
    00181             D.Out(pdInit, "deja cree");
    00182             }
    00183         }
    00184
    00185     G.Out(pdGendoc,"exit FederationManagement::createFederationExecution");
    00186
    00187 }
    00188
    00189
    00190 // ----------------------------------------------------------------------------
    00192 void
    00193 FederationManagement::
    00194 destroyFederationExecution(std::string theName,
    00195                            TypeException &e)
    00196 {
    00197     NM_Destroy_Federation_Execution requete ;
    00198
    00199     D.Out(pdInit, "Destroy Federation %s.", theName.c_str());
    00200     G.Out(pdGendoc,"enter FederationManagement::destroyFederationExecution");
    00201     e = e_NO_EXCEPTION ;
    00202
    00203     // BUG: On devrait pouvoir detruire une federation meme si on n'est
    00204     // pas le createur.
    00205     //if (strcmp(theName, _nom_federation))
    00206     //    e = e_FederationExecutionDoesNotExist ;
    00207
    00208     if (e == e_NO_EXCEPTION)
    00209         {
    00210         requete.federation = _numero_federation ;
    00211         requete.federate = federate ;
    00212         requete.federationName = theName;
    00213
    00214         G.Out(pdGendoc,"destroyFederationExecution====>send Message to RTIG");
    00215
    00216         comm->sendMessage(&requete);
    00217
    00218         std::auto_ptr<NetworkMessage> reponse(comm->waitMessage(
    00219                           NetworkMessage::DESTROY_FEDERATION_EXECUTION,
    00220                           federate));
    00221
    00222         if (reponse->exception == e_NO_EXCEPTION) {
    00223             _nom_federation    = "" ;
    00224             _numero_federation = 0 ;
    00225             _fin_execution     = true ;
    00226             // Now, remove temporary file (if not yet done)
    00227             if ( _FEDid.c_str() != NULL )
    00228                {
    00229                if ( _FEDid[0] != '\0' )
    00230                    {
    00231                    // If RTIA end (abort ?) before join don't remove file if not temporary
    00232                    // temporary file name begins with _RT ( yes, but...)
    00233                    if ( _FEDid[0] == '_' || _FEDid[1] == 'R' || _FEDid[2] == 'T')
    00234                       {
    00235                       std::cout<<"Removing temporary file "<<_FEDid<<" on destroy federation."<<std::endl;
    00236                       std::remove(_FEDid.c_str());
    00237                       _FEDid[0] = '\0' ;
    00238                       }
    00239                    else
    00240                       {
    00241                       std::cout<<"** W ** I don't remove file "<<_FEDid<<std::endl;
    00242                       }
    00243                    }
    00244                }
    00245             }
    00246         else
    00247             {
    00248             // There is an exception so destroy may be not done on RTIG
    00249             e = reponse->exception ;
    00250             }
    00251     }
    00252
    00253 G.Out(pdGendoc,"exit  FederationManagement::destroyFederationExecution");
    00254 }
    00255
    00256 // ----------------------------------------------------------------------------
    00258 FederateHandle
    00259 FederationManagement::
    00260 joinFederationExecution(std::string Federate,
    00261                         std::string Federation,
    00262                         TypeException &e)
    00263 {
    00264     NM_Join_Federation_Execution requete;
    00265     NM_Get_FED_File              requeteFED;
    00266
    00267     int i, nb ;
    00268     string filename ; // Needed for working file name
    00269
    00270     G.Out(pdGendoc,"enter FederationManagement::joinFederationExecution");
    00271     D.Out(pdInit, "Join Federation %s as %s.", Federation.c_str(), Federate.c_str());
    00272
    00273     e = e_NO_EXCEPTION ;
    00274
    00275     // this federate, may be, has yet joined federation so don't disturb RTIG
    00276     if (_est_membre_federation){
    00277           e = e_FederateAlreadyExecutionMember ;
    00278          return(0);
    00279     }
    00280
    00281     if (e == e_NO_EXCEPTION)
    00282         {
    00283         requete.federationName = Federation;
    00284         requete.federateName   = Federate;
    00285
    00286         requete.bestEffortAddress = comm->getAddress();
    00287         requete.bestEffortPeer = comm->getPort();
    00288
    00289         G.Out(pdGendoc,"joinFederationExecution====>send Message to RTIG");
    00290
    00291         comm->sendMessage(&requete);
    00292
    00293         // Waiting RTIG answer for FED file opened
    00294         std::auto_ptr<NetworkMessage> reponse(comm->waitMessage(NetworkMessage::GET_FED_FILE, 0));
    00295         NM_Get_FED_File*  getFedMsg = static_cast<NM_Get_FED_File*>(reponse.get());
    00296
    00297         if ( reponse->exception != e_NO_EXCEPTION)
    00298             {
    00299             // Bad answer from RTIG
    00300             e = reponse->exception ;
    00301             }
    00302         else
    00303             {
    00304         stat->rtiService(NetworkMessage::GET_FED_FILE);
    00305             // RTIA have to open a new file for working
    00306             // We have to build a name for working file, name begins by _RTIA_ (6 char)
    00307             // First pid converted in char and added
    00308             // Then federation name
    00309             // File type (4)
    00310             char pid_name[10];
    00311             sprintf(pid_name,"%d_",getpid());
    00312
    00313             #ifdef _WIN32   //Write the file into
    00314             char    *theDir;
    00315
    00316             theDir= getenv("TMP"); if (theDir == NULL) theDir= getenv("TEMP");
    00317             if (theDir) { filename+= theDir; filename+= "\\";}
    00318             #endif
    00319
    00320             filename+= "_RTIA_";
    00321             filename+= pid_name ;
    00322             filename+= Federation ;
    00323             // Last file type : fed or xml ?
    00324
    00325             string filename_RTIG = reponse->FEDid ;
    00326             int nbcar_filename_RTIG=filename_RTIG.length();
    00327             string extension = filename_RTIG.substr(nbcar_filename_RTIG-3,3) ;
    00328               if ( !strcasecmp(extension.c_str(),"fed") )
    00329                   {
    00330                   filename += ".fed";
    00331                   }
    00332               else if  ( !strcasecmp(extension.c_str(),"xml") )
    00333                   {
    00334                   filename += ".xml";
    00335                   }
    00336               else
    00337                   throw CouldNotOpenFED("nor .fed nor .xml");
    00338             // FED filename for working must be stored
    00339             _FEDid = filename ;
    00340             // RTIA opens working file
    00341             std::ofstream fedWorkFile(filename.c_str());
    00342             if ( !fedWorkFile.is_open()) {
    00343                 throw RTIinternalError("FED file has vanished.") ;
    00344             }
    00345
    00346             // RTIA says RTIG OK for file transfer
    00347             requeteFED.federateName = Federate;
    00348             requeteFED.FEDid = filename;
    00349             if ( e == e_NO_EXCEPTION)
    00350                 requeteFED.number = 0 ;  // OK for open
    00351             else
    00352                 requeteFED.number = 1 ;
    00353
    00354             G.Out(pdGendoc,"joinFederationExecution====> begin FED file get from RTIG");
    00355
    00356             comm->sendMessage(&requeteFED);
    00357
    00358             // Now read loop from RTIG to get line contents and then write it into file
    00359             int num_line = 0 ; // no line read
    00360             for (;;)
    00361                 {
    00362                 reponse.reset(comm->waitMessage(NetworkMessage::GET_FED_FILE, 0));
    00363                 getFedMsg = static_cast<NM_Get_FED_File*>(reponse.get());
    00364                 if ( reponse->exception != e_NO_EXCEPTION)
    00365                     {
    00366                     cout << "Bad answer from RTIG" << endl ;
    00367                     e = e_RTIinternalError ;
    00368                     break ;
    00369                     }
    00370                 stat->rtiService(NetworkMessage::GET_FED_FILE);
    00371                 // Line read
    00372                 num_line++ ;
    00373                 // Check for EOF
    00374                 if ( reponse->number == 0 ) break;
    00375
    00376                 assert ( num_line == reponse->number ) ;
    00377                 reponse->handleArraySize = 1 ;
    00378                 fedWorkFile << getFedMsg->getFEDLine();
    00379                 // RTIA says OK to RTIG
    00380                 requeteFED.federateName =Federate;
    00381                 requeteFED.number = num_line ;
    00382                 requeteFED.FEDid = filename;
    00383                 comm->sendMessage(&requeteFED);
    00384                 }
    00385             // close working file
    00386             fedWorkFile.close();
    00387             }
    00388
    00389         G.Out(pdGendoc,"joinFederationExecution====> end FED file get from RTIG");
    00390
    00391          // Waiting RTIG answer (from any federate)
    00392         reponse.reset(comm->waitMessage(NetworkMessage::JOIN_FEDERATION_EXECUTION, 0));
    00393
    00394         // If OK, regulators number is inside the answer.
    00395         // Then we except a NULL message from each.
    00396         if (reponse->exception == e_NO_EXCEPTION) {
    00397             _nom_federation = std::string(Federation);
    00398             _nom_federe =  std::string(Federate);
    00399             _numero_federation = reponse->federation ;
    00400             federate = reponse->federate ;
    00401             tm->setFederate(reponse->federate);
    00402
    00403 #ifdef FEDERATION_USES_MULTICAST
    00404             // creation du socket pour la communication best-effort
    00405             comm->CreerSocketMC(reponse->AdresseMulticast, MC_PORT);
    00406 #endif
    00407
    00408             nb = reponse->numberOfRegulators ;
    00409             for (i=0 ; i<nb ; i++) {
    00410                 reponse.reset(comm->waitMessage(NetworkMessage::MESSAGE_NULL, 0));
    00411                 assert(tm != NULL);
    00412                 tm->insert(reponse->federate, reponse->getDate());
    00413             }
    00414
    00415             _est_membre_federation = true ;
    00416             G.Out(pdGendoc,"exit(%d) FederationManagement::joinFederationExecution",federate);
    00417             return(federate);
    00418         }
    00419         else
    00420             e = reponse->exception ;
    00421     }
    00422     G.Out(pdGendoc,"exit(0) FederationManagement::joinFederationExecution");
    00423     return(0);
    00424 }
    00425
    00426 // -------------------------------
    00427 // -- resignFederationExecution --
    00428 // -------------------------------
    00429
    00430 void
    00431 FederationManagement::resignFederationExecution(RTI::ResignAction,
    00432                                                 TypeException &e)
    00433 {
    00434     NM_Resign_Federation_Execution msg;
    00435     TypeException exception = e_NO_EXCEPTION ;
    00436
    00437     G.Out(pdGendoc,"enter FederationManagement::resignFederationExecution");
    00438
    00439     e = e_NO_EXCEPTION ;
    00440
    00441     D.Out(pdInit, "Resign Federation.");
    00442
    00443     if (!_est_membre_federation)
    00444         e = e_FederateNotExecutionMember ;
    00445
    00446     if (e == e_NO_EXCEPTION) {
    00447         tm->StopperAvanceTemps();
    00448
    00449         if (tm->requestRegulateurState())
    00450             tm->setTimeRegulating(false,0,0, exception);
    00451
    00452         msg.federation = _numero_federation ;
    00453         msg.federate = federate ;
    00454
    00455         G.Out(pdGendoc,"      resignFederationExecution ===> send NMessage RFE to RTIG");
    00456         comm->sendMessage(&msg);
    00457
    00458         // WAIT FOR RTIG answer
    00459         std::auto_ptr<NetworkMessage> reponse(comm->waitMessage(NetworkMessage::RESIGN_FEDERATION_EXECUTION, federate));
    00460
    00461         _est_membre_federation = false ;
    00462         _numero_federation = 0 ;
    00463         federate = 0 ;
    00464         // Now, remove temporary file (if not yet done)
    00465         if ( _FEDid.c_str() != NULL)
    00466             {
    00467             if ( _FEDid[0] != '\0' )
    00468                 {
    00469                 std::cout<<"Removing temporary file "<<_FEDid<<" on resign federation."<<std::endl;
    00470                 std::remove(_FEDid.c_str());
    00471                 _FEDid[0] = '\0' ;
    00472                 }
    00473             }
    00474         G.Out(pdGendoc,"exit  FederationManagement::resignFederationExecution");
    00475         }
    00476     else
    00477         {
    00478         G.Out(pdGendoc,"exit  FederationManagement::resignFederationExecution on exception");
    00479         }
    00480 }
    00481
    00482 // ----------------------------------------------------------------------------
    00484 void
    00485 FederationManagement::registerSynchronization(std::string label,
    00486                                               std::string tag,
    00487                                               TypeException &e)
    00488 {
    00489     D.Out(pdProtocol, "RegisterSynchronization.");
    00490     G.Out(pdGendoc,"enter FederationManagement::registerSynchronization");
    00491
    00492     //assert(label != NULL);
    00493
    00494     e = e_NO_EXCEPTION ;
    00495
    00496     list<char *>::const_iterator i = synchronizationLabels.begin();
    00497     bool exists = false ;
    00498     for (; i != synchronizationLabels.end(); i++) {
    00499         if (!strcmp((*i), label.c_str())) {
    00500             e = e_FederationAlreadyPaused ; // Label already pending.
    00501             exists = true ;
    00502             break ;
    00503         }
    00504     }
    00505
    00506     if (!exists)
    00507         synchronizationLabels.push_back(strdup(label.c_str()));
    00508
    00509     if (!_est_membre_federation)
    00510         e = e_FederateNotExecutionMember ;
    00511
    00512     if (e == e_NO_EXCEPTION) {
    00513         NM_Register_Federation_Synchronization_Point req ;
    00514         req.federation = _numero_federation ;
    00515         req.federate = federate ;
    00516         req.setLabel(label);
    00517         req.setTag(tag);
    00518         // no federates set so boolean must be false
    00519         req.setDoesNotExist();
    00520
    00521         G.Out(pdGendoc,"      registerSynchronization====> send Message to RTIG");
    00522
    00523         comm->sendMessage(&req);
    00524     }
    00525
    00526     G.Out(pdGendoc,"exit  FederationManagement::registerSynchronization");
    00527
    00528 }
    00529
    00530 // ----------------------------------------------------------------------------
    00532 void
    00533 FederationManagement::registerSynchronization(std::string label,
    00534                                               std::string tag,
    00535                                               unsigned short array_size,
    00536                                               std::vector <FederateHandle> &fed_array,
    00537                                               TypeException &e)
    00538 {
    00539     D.Out(pdProtocol, "RegisterSynchronization.");
    00540     G.Out(pdGendoc,"enter FederationManagement::registerSynchronization with federate set");
    00541
    00542     //assert(label != NULL);
    00543
    00544     e = e_NO_EXCEPTION ;
    00545
    00546     list<char *>::const_iterator i = synchronizationLabels.begin();
    00547     bool exists = false ;
    00548     for (; i != synchronizationLabels.end(); i++) {
    00549         if (!strcmp((*i), label.c_str())) {
    00550             e = e_FederationAlreadyPaused ; // Label already pending.
    00551             exists = true ;
    00552             break ;
    00553         }
    00554     }
    00555
    00556     if (!exists)
    00557         synchronizationLabels.push_back(strdup(label.c_str()));
    00558
    00559     if (!_est_membre_federation)
    00560         e = e_FederateNotExecutionMember ;
    00561
    00562     if (e == e_NO_EXCEPTION) {
    00563         NM_Register_Federation_Synchronization_Point req;
    00564         req.federation = _numero_federation ;
    00565         req.federate = federate ;
    00566         req.setLabel(label);
    00567         req.setTag(tag);
    00568         /* the synchronization point concerns a set of federate */
    00569         req.setExist();
    00570         req.handleArraySize = array_size ;
    00571         req.handleArray.resize(array_size) ;
    00572         for ( int j=0 ; j < array_size ; j++)
    00573             req.handleArray[j] = fed_array[j] ;
    00574
    00575         G.Out(pdGendoc,"      registerSynchronization====> send Message to RTIG");
    00576
    00577         comm->sendMessage(&req);
    00578     }
    00579
    00580     G.Out(pdGendoc,"exit  FederationManagement::registerSynchronization with federate set");
    00581
    00582 }
    00583 // ----------------------------------------------------------------------------
    00585 void
    00586 FederationManagement::unregisterSynchronization(std::string label,
    00587                                                 TypeException &e)
    00588 {
    00589     D.Out(pdProtocol, "unregisterSynchronization.");
    00590
    00591     //assert(label != NULL);
    00592
    00593     e = e_NO_EXCEPTION ;
    00594
    00595     // Find if this label has been requested by federate or RTIG.
    00596     list<char *>::iterator i = synchronizationLabels.begin();
    00597     bool exists = false ;
    00598     for (; i != synchronizationLabels.end(); ++i) {
    00599         if (!strcmp((*i), label.c_str())) {
    00600             // Label already pending.
    00601             exists = true ;
    00602             break ;
    00603         }
    00604     }
    00605     if (!exists)
    00606         e = e_UnknownLabel ;
    00607     else {
    00608       /* delete[] *i ;
    00609        * the label has been allocated using strdup (i.e. malloc-like)
    00610        * so that we MUST use free (and not delete[]) to free it :))
    00611        */
    00612       free(*i);
    00613       synchronizationLabels.erase(i);
    00614     }
    00615
    00616     if (!_est_membre_federation)
    00617         e = e_FederateNotExecutionMember ;
    00618
    00619     if (e == e_NO_EXCEPTION) {
    00620         NM_Synchronization_Point_Achieved req ;
    00621
    00622         req.federation = _numero_federation ;
    00623         req.federate = federate ;
    00624         req.setLabel(label);
    00625
    00626         comm->sendMessage(&req);
    00627     }
    00628 }
    00629
    00630 // ----------------------------------------------------------------------------
    00631 void
    00632 FederationManagement::announceSynchronizationPoint(const char *label,
    00633                                                    const char *tag)
    00634 {
    00635     D.Out(pdInit, "Announce Synchronization Point \"%s\"(%s).", label, tag);
    00636
    00637     Message req;
    00638
    00639     assert(label != NULL);
    00640
    00641     req.type = Message::ANNOUNCE_SYNCHRONIZATION_POINT ;
    00642     req.setLabel(label);
    00643     req.setTag(tag);
    00644
    00645     // adding label to list of synchronizations to be done.
    00646     list<char *>::const_iterator i = synchronizationLabels.begin();
    00647     bool exists = false ;
    00648     for (; i != synchronizationLabels.end(); i++) {
    00649         if (!strcmp((*i), label)) {
    00650             // label exists (only if initiator).
    00651             exists = true ;
    00652             break ;
    00653         }
    00654     }
    00655     if (!exists)
    00656         synchronizationLabels.push_back(strdup(label));
    00657
    00658     comm->requestFederateService(&req);
    00659 }
    00660
    00661 // ----------------------------------------------------------------------------
    00662 void FederationManagement::
    00663 synchronizationPointRegistrationFailed(const char *label)
    00664 {
    00665     D.Out(pdInit, "Synchronization Point Registration Failed \"%s\".",
    00666           label);
    00667
    00668     Message req;
    00669
    00670     G.Out(pdGendoc,"enter FederationManagement::synchronizationPointRegistrationFailed");
    00671
    00672     assert(label != NULL);
    00673
    00674     req.type = Message::SYNCHRONIZATION_POINT_REGISTRATION_FAILED ;
    00675     req.setLabel(label);
    00676
    00677     comm->requestFederateService(&req);
    00678
    00679     G.Out(pdGendoc,"exit  FederationManagement::synchronizationPointRegistrationFailed");
    00680
    00681 }
    00682
    00683 // ----------------------------------------------------------------------------
    00684 void FederationManagement::
    00685 synchronizationPointRegistrationSucceeded(const char *label)
    00686 {
    00687     D.Out(pdInit, "Synchronization Point Registration Succeeded \"%s\".",
    00688           label);
    00689
    00690     Message req;
    00691
    00692     G.Out(pdGendoc,"enter FederationManagement::synchronizationPointRegistrationSucceeded");
    00693
    00694     assert(label != NULL);
    00695
    00696     req.type = Message::SYNCHRONIZATION_POINT_REGISTRATION_SUCCEEDED ;
    00697     req.setLabel(label);
    00698
    00699     comm->requestFederateService(&req);
    00700
    00701     G.Out(pdGendoc,"exit  FederationManagement::synchronizationPointRegistrationSucceeded");
    00702
    00703 }
    00704
    00705 // ----------------------------------------------------------------------------
    00706 void
    00707 FederationManagement::federationSynchronized(const char *label)
    00708 {
    00709     D.Out(pdInit, "Federation Synchronized \"%s\".", label);
    00710
    00711     Message req;
    00712
    00713     assert(label != NULL);
    00714
    00715     req.type = Message::FEDERATION_SYNCHRONIZED ;
    00716     req.setLabel(label);
    00717
    00718     comm->requestFederateService(&req);
    00719 }
    00720
    00721 // ----------------------------------------------------------------------------
    00722 // requestFederationSave with time
    00723 void
    00724 FederationManagement::requestFederationSave(std::string label,
    00725                                             FederationTime the_time,
    00726                                             TypeException &e)
    00727 {
    00728     D.Out(pdInit, "Request for federation save \"%s\".", label.c_str());
    00729     G.Out(pdGendoc,"enter FederationManagement::requestFederationSave "
    00730                    "with time");
    00731
    00732     //assert(label != 0);
    00733
    00734     NM_Request_Federation_Save req ;
    00735
    00736     req.setDate(the_time);
    00737     req.setLabel(label);
    00738     req.federation = _numero_federation ;
    00739     req.federate = federate ;
    00740
    00741     G.Out(pdGendoc,"      requestFederationSave====>send Message R_F_S to RTIG");
    00742
    00743     comm->sendMessage(&req);
    00744
    00745     // Should make sure that RTIG don't have any save or restore recently set.
    00746     // NetworkMessage rep ;
    00747     // comm->waitMessage(&rep, NetworkMessage::REQUEST_FEDERATION_SAVE, federate);
    00748     // e = rep.exception ;
    00749 }
    00750
    00751 // ----------------------------------------------------------------------------
    00752 // requestFederationSave without time
    00753 void
    00754 FederationManagement::requestFederationSave(std::string label,
    00755                                             TypeException &e)
    00756 {
    00757     D.Out(pdInit, "Request for federation save \"%s\".", label.c_str());
    00758     G.Out(pdGendoc,"enter FederationManagement::requestFederationSave "
    00759                    "without time");
    00760
    00761     //assert(label != 0);
    00762
    00763     NM_Request_Federation_Save req ;
    00764
    00765     req.setLabel(label);
    00766     req.federation = _numero_federation ;
    00767     req.federate = federate ;
    00768     G.Out(pdGendoc,"      requestFederationSave====>send Message R_F_S to RTIG");
    00769
    00770     comm->sendMessage(&req);
    00771
    00772     G.Out(pdGendoc,"exit  FederationManagement::requestFederationSave "
    00773                    "without time");
    00774 }
    00775
    00776 // ----------------------------------------------------------------------------
    00777 void
    00778 FederationManagement::federateSaveBegun(TypeException &)
    00779 {
    00780     G.Out(pdGendoc,"enter FederationManagement::federateSaveBegun");
    00781     D.Out(pdInit, "Beginning federate save.");
    00782
    00783     if (!savingState)
    00784         throw SaveNotInitiated("Federation did not initiate saving.");
    00785
    00786     NM_Federate_Save_Begun req ;
    00787
    00788     req.federate = federate ;
    00789     req.federation = _numero_federation ;
    00790
    00791     G.Out(pdGendoc,"      federateSaveBegun ====>send Message F_S_B to RTIG");
    00792
    00793     comm->sendMessage(&req);
    00794
    00795     G.Out(pdGendoc,"exit  FederationManagement::federateSaveBegun");
    00796 }
    00797
    00798 // ----------------------------------------------------------------------------
    00799 void
    00800 FederationManagement::federateSaveStatus(bool status, TypeException &)
    00801 {
    00802     G.Out(pdGendoc,"enter FederationManagement::federateSaveStatus");
    00803     D.Out(pdInit, "Federate %ssaved.", status ? "" : "not ");
    00804
    00805     if (!savingState)
    00806         throw SaveNotInitiated("Federation did not initiate saving.");
    00807
    00808     std::auto_ptr<NetworkMessage> req(NM_Factory::create(status ? NetworkMessage::FEDERATE_SAVE_COMPLETE : NetworkMessage::FEDERATE_SAVE_NOT_COMPLETE));
    00809
    00810     req->federate = federate ;
    00811     req->federation = _numero_federation ;
    00812
    00813     if (status)
    00814        {
    00815        G.Out(pdGendoc,"      federateSaveStatus ====>send Message F_S_C to RTIG");
    00816        }
    00817     else
    00818        {
    00819        G.Out(pdGendoc,"      federateSaveStatus ====>send Message F_S_N_C to RTIG");
    00820        }
    00821
    00822     comm->sendMessage(req.get());
    00823
    00824     G.Out(pdGendoc,"exit  FederationManagement::federateSaveStatus");
    00825 }
    00826
    00827 // ----------------------------------------------------------------------------
    00828 void
    00829 FederationManagement::initiateFederateSave(const char *label)
    00830 {
    00831     G.Out(pdGendoc,"enter FederationManagement::initiateFederateSave");
    00832     D.Out(pdInit, "Initiate a federate save \"%s\".", label);
    00833
    00834     savingState = true ;
    00835
    00836     Message req;
    00837
    00838     assert(label != 0);
    00839
    00840     req.type = Message::INITIATE_FEDERATE_SAVE ;
    00841     req.setLabel(label);
    00842
    00843     comm->requestFederateService(&req);
    00844
    00845     G.Out(pdGendoc,"exit  FederationManagement::initiateFederateSave");
    00846 }
    00847
    00848 // ----------------------------------------------------------------------------
    00849 void
    00850 FederationManagement::federationSavedStatus(bool status)
    00851 {
    00852     G.Out(pdGendoc,"enter FederationManagement::federationSavedStatus");
    00853     D.Out(pdInit, "Federation %ssaved.", status ? "" : "not ");
    00854
    00855     savingState = false ;
    00856
    00857     Message req;
    00858
    00859     req.type = status ? Message::FEDERATION_SAVED : Message::FEDERATION_NOT_SAVED ;
    00860
    00861     comm->requestFederateService(&req);
    00862
    00863     G.Out(pdGendoc,"exit  FederationManagement::federationSavedStatus");
    00864 }
    00865
    00866 // ----------------------------------------------------------------------------
    00867 void
    00868 FederationManagement::requestFederationRestore(std::string label,
    00869                                                TypeException &)
    00870 {
    00871     G.Out(pdGendoc,"enter FederationManagement::requestFederationRestore");
    00872     D.Out(pdInit, "Request for federation restore \"%s\".", label.c_str());
    00873
    00874     //assert(label != NULL);
    00875
    00876     NM_Request_Federation_Restore req ;
    00877
    00878     req.setLabel(label);
    00879     req.federate = federate ;
    00880     req.federation = _numero_federation ;
    00881
    00882     G.Out(pdGendoc,"     requestFederationRestore  ====>send Message R_F_R to RTIG");
    00883
    00884     comm->sendMessage(&req);
    00885
    00886     // Should make sure that RTIG don't have any save or restore recently set.
    00887     // ...
    00888     G.Out(pdGendoc,"exit  FederationManagement::requestFederationRestore");
    00889 }
    00890
    00891 // ----------------------------------------------------------------------------
    00892 void
    00893 FederationManagement::federateRestoreStatus(bool status, TypeException &)
    00894 {
    00895     D.Out(pdInit, "Federate %srestored.", status ? "" : "not ");
    00896
    00897     if (!restoringState)
    00898         throw RestoreNotRequested("Federation did not initiate restoring.");
    00899
    00900     std::auto_ptr<NetworkMessage> req(NM_Factory::create(status ? NetworkMessage::FEDERATE_RESTORE_COMPLETE : NetworkMessage::FEDERATE_RESTORE_NOT_COMPLETE));
    00901     req->federate = federate ;
    00902     req->federation = _numero_federation ;
    00903     comm->sendMessage(req.get());
    00904 }
    00905
    00906 // ----------------------------------------------------------------------------
    00907 void
    00908 FederationManagement::requestFederationRestoreStatus(bool status,
    00909                                                      const char *label,
    00910                                                      const char *reason)
    00911 {
    00912     G.Out(pdGendoc,"enter FederationManagement::requestFederationRestoreStatus");
    00913     D.Out(pdInit, "Federation restore request %saccepted",
    00914           status ? "" : "not ");
    00915
    00916     Message req;
    00917
    00918     req.setLabel(label);
    00919
    00920     if (status)
    00921         req.type = Message::REQUEST_FEDERATION_RESTORE_SUCCEEDED ;
    00922     else {
    00923         req.type = Message::REQUEST_FEDERATION_RESTORE_FAILED ;
    00924         req.setTag(reason);
    00925     }
    00926
    00927     comm->requestFederateService(&req);
    00928     G.Out(pdGendoc,"exit  FederationManagement::requestFederationRestoreStatus");
    00929 }
    00930
    00931 // ----------------------------------------------------------------------------
    00932 void
    00933 FederationManagement::federationRestoreBegun()
    00934 {
    00935     G.Out(pdGendoc,"enter FederationManagement::federationRestoreBegun");
    00936     D.Out(pdInit, "Federation restore begun");
    00937
    00938     Message req;
    00939     req.type = Message::FEDERATION_RESTORE_BEGUN ;
    00940
    00941     comm->requestFederateService(&req);
    00942
    00943     G.Out(pdGendoc,"exit  FederationManagement::federationRestoreBegun");
    00944 }
    00945
    00946 // ----------------------------------------------------------------------------
    00947 void
    00948 FederationManagement::initiateFederateRestore(const char *label,
    00949                                               FederateHandle handle)
    00950 {
    00951     G.Out(pdGendoc,"enter FederationManagement::initiateFederateRestore");
    00952     D.Out(pdInit, "Initiate federate restore \"%s\" with federate handle %d.",
    00953           label, handle);
    00954
    00955     restoringState = true ;
    00956
    00957     Message req;
    00958     req.type = Message::INITIATE_FEDERATE_RESTORE ;
    00959     req.setFederate(handle);
    00960     req.setLabel(label);
    00961
    00962     comm->requestFederateService(&req);
    00963     G.Out(pdGendoc,"exit  FederationManagement::initiateFederateRestore");
    00964 }
    00965
    00966 // ----------------------------------------------------------------------------
    00967 void
    00968 FederationManagement::federationRestoredStatus(bool status)
    00969 {
    00970     D.Out(pdInit, "Federation %srestored.", status ? "" : "not ");
    00971
    00972     restoringState = false ;
    00973
    00974     Message req;
    00975
    00976     if (status)
    00977         req.type = Message::FEDERATION_RESTORED ;
    00978     else
    00979         req.type = Message::FEDERATION_NOT_RESTORED ;
    00980
    00981     comm->requestFederateService(&req);
    00982 }
    00983
    00984 // ----------------------------------------------------------------------------
    00985 void
    00986 FederationManagement::checkFederationSaving()
    00987     throw (SaveInProgress)
    00988 {
    00989     if (savingState) {
    00990         throw SaveInProgress("Federation is in saving state");
    00991     }
    00992 }
    00993
    00994 // ----------------------------------------------------------------------------
    00995 void
    00996 FederationManagement::checkFederationRestoring()
    00997     throw (RestoreInProgress)
    00998 {
    00999     if (restoringState) {
    01000         throw RestoreInProgress("Federation is in restoring state");
    01001     }
    01002 }
    01003
    01004 }} // namespace certi/rtia
    01005