Federation.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: Federation.cc,v 3.105 2009/04/08 10:47:18 approx Exp $
00022 // ----------------------------------------------------------------------------
00023 
00024 #include <config.h>
00025 #include "Federation.hh"
00026 #include "NM_Classes.hh"
00027 #include <sstream>
00028 #include <cassert>
00029 #include <memory>
00030 
00031 #include "fed.hh"
00032 #include "XmlParser.hh"
00033 #include "Object.hh"
00034 #include "ObjectAttribute.hh"
00035 #include "ObjectSet.hh"
00036 #include "ObjectClassSet.hh"
00037 #include "InteractionSet.hh"
00038 
00039 #include "ObjectClassAttribute.hh"
00040 #include "PrettyDebug.hh"
00041 #include "LBTS.hh"
00042 #include "NM_Classes.hh"
00043 
00044 #ifdef _WIN32
00045 #include <windows.h>
00046 #include <time.h>
00047 #include <sys/types.h>
00048 #include <sys/stat.h>
00049 #include <stdio.h>
00050 #else
00051 #include <map>
00052 #include <fstream>
00053 #include <iostream>
00054 #include <string.h>
00055 #include <sys/types.h>
00056 #include <sys/stat.h>
00057 #include <unistd.h>
00058 #include <errno.h>
00059 #endif
00060 
00061 using std::pair ;
00062 using std::ifstream ;
00063 using std::ios ;
00064 using std::cout ;
00065 using std::endl ;
00066 using std::string ;
00067 using std::list ;
00068 using std::cerr ;
00069 using std::vector ;
00070 
00071 // Definitions
00072 #ifdef HAVE_XML
00073 #define ROOT_NODE (const xmlChar*) "rtigSaveData"
00074 #define NODE_FEDERATION (const xmlChar*) "federation"
00075 #define NODE_FEDERATE (const xmlChar*) "federate"
00076 #endif // HAVE_XML
00077 
00078 namespace certi {
00079 
00080 class XmlParser ;
00081 
00082 namespace rtig {
00083 
00084 static PrettyDebug D("FEDERATION", __FILE__);
00085 static PrettyDebug G("GENDOC",__FILE__);
00086 
00098 #ifdef FEDERATION_USES_MULTICAST
00099 
00100 Federation::Federation(const char *federation_name,
00101                        FederationHandle federation_handle,
00102                        SocketServer &socket_server,
00103                        AuditFile &audit_server,
00104                        SocketMC *mc_link,
00105                        int theVerboseLevel)
00106 #else
00107     Federation::Federation(const char *federation_name,
00108                            Handle federation_handle,
00109                            SocketServer &socket_server,
00110                            AuditFile &audit_server,
00111                            const char *FEDid_name,
00112                            int theVerboseLevel)
00113 #endif
00114     throw (CouldNotOpenFED, ErrorReadingFED, MemoryExhausted, SecurityError,
00115            RTIinternalError)
00116     : federateHandles(1), objectHandles(1), saveInProgress(false),
00117       restoreInProgress(false), saveStatus(true), restoreStatus(true),
00118       verboseLevel(theVerboseLevel)
00119 
00120 {
00121     //    fedparser::FedParser *fed_reader ;
00122   STAT_STRUCT file_stat;
00123 
00124 #ifdef FEDERATION_USES_MULTICAST // -----------------
00125     // Initialize Multicast
00126     if (mc_link == NULL) {
00127         D.Out(pdExcept, "Null Multicast socket for new Federation.");
00128         throw RTIinternalError("NULL Multicast socket for new Federation.");
00129     }
00130 
00131     D.Out(pdInit, "New Federation %d will use Multicast.", federation_handle);
00132     MCLink = mc_link ;
00133 #endif // FEDERATION_USES_MULTICAST // --------------
00134 
00135     G.Out(pdGendoc,"enter Federation::Federation");
00136     // Allocates Name
00137     if ((federation_name == NULL) || (federation_handle == 0))
00138         throw RTIinternalError("Null init parameter in Federation creation.");
00139 
00140     name = std::string(federation_name);
00141 
00142     // Default Attribute values
00143     handle = federation_handle;
00144     FEDid  = std::string(FEDid_name);
00145 
00146     D.Out(pdInit, "New Federation created with Handle %d, now reading FOM.",
00147           handle);
00148 
00149     // Initialize the Security Server.
00150     server = new SecurityServer(socket_server, audit_server, handle);
00151 
00152     // Read FOM File to initialize Root Object.
00153     root = new RootObject(server);
00154 
00155     if (verboseLevel>0) {
00156         cout << "New federation: " << name << endl ;
00157     }
00158 
00159     // We should try to open FOM file from different
00160     // predefined places:
00161     //
00162     // 1 - bare filename considered as a path provided through FEDid_name
00163     //
00164     // 2 - getenv(CERTI_HOME)+"/share/federations"+ FEDid_name
00165     //
00166     // 3 - default (unix) installation place plus FEDid_name
00167     //     "/usr/local/share/federation/" + FEDid_name
00168     //
00169     string filename   = FEDid;
00170     bool   filefound  = false;
00171     if (verboseLevel>0) {
00172         cout << "Looking for FOM file... " << endl ;
00173 
00174         cout << "   Trying... " << filename;
00175     }
00176     filefound = (0==STAT_FUNCTION(filename.c_str(),&file_stat));
00177 
00178 #ifdef _WIN32
00179     if (!filefound) {
00180       char temp[260];
00181       if (verboseLevel>0) {
00182           cout << " --> cannot access." <<endl;
00183       }
00184       GetCurrentDirectory(260,temp);
00185       filename = string(temp);
00186       filename = filename + "\\share\\federations\\"+string(FEDid_name);
00187       if (verboseLevel>0) {
00188           cout << "   Now trying..." << filename;
00189       }
00190       filefound = (0==STAT_FUNCTION(filename.c_str(),&file_stat));
00191     }
00192 
00193     if (!filefound && (NULL!=getenv("CERTI_HOME"))) {
00194       if (verboseLevel>0) {
00195             cout << " --> cannot access." <<endl;
00196       }
00197       filename = string(getenv("CERTI_HOME"))+"\\share\\federations\\"+FEDid_name;
00198       if (verboseLevel>0) {
00199         cout << "   Now trying..." << filename;
00200       }
00201       filefound = (0==STAT_FUNCTION(filename.c_str(),&file_stat));
00202     }
00203 #else
00204     if (!filefound) {
00205       if (verboseLevel>0) {
00206          cout << " --> cannot access." <<endl;
00207       }
00208       filename = "/usr/local/share/federations/"+string(FEDid_name);
00209       if (verboseLevel>0) {
00210          cout << "   Now trying..." << filename;
00211       }
00212       filefound = (0==STAT_FUNCTION(filename.c_str(),&file_stat));
00213     }
00214 
00215     if (!filefound && (NULL!=getenv("CERTI_HOME"))) {
00216       if (verboseLevel>0) {
00217          cout << " --> cannot access." <<endl;
00218       }
00219       filename = string(getenv("CERTI_HOME"))+"/share/federations/"+FEDid_name;
00220       if (verboseLevel>0) {
00221          cout << "   Now trying..." << filename;
00222       }
00223       filefound = (0==STAT_FUNCTION(filename.c_str(),&file_stat));
00224     }
00225 #endif
00226 
00227     if (!filefound) {
00228       if (verboseLevel>0) {
00229         cout << " --> cannot access." <<endl;
00230       }
00231       cerr << "Next step will fail"<<endl;
00232       G.Out(pdGendoc,"exit Federation::Federation on exception CouldNotOpenFED");
00233       throw CouldNotOpenFED("RTIG cannot find FED file.");
00234     }
00235 
00236     // now really assign FEDid
00237     FEDid = filename;
00238 
00239     // Try to open to verify if file exists
00240     std::ifstream fedTry(FEDid.c_str());
00241     if (!fedTry.is_open())
00242         {
00243         if (verboseLevel>0) {
00244            cout << "... failed : ";
00245         }
00246         G.Out(pdGendoc,"exit Federation::Federation on exception CouldNotOpenFED");
00247         throw CouldNotOpenFED("RTIG have found but cannot open FED file");
00248         }
00249     else {
00250         if (verboseLevel>0) {
00251             cout << "... opened." << endl ;
00252         }
00253         fedTry.close();
00254     }
00255 
00256     int  nbcar_filename = filename.length() ;
00257     bool is_a_fed       = false ;
00258     bool is_an_xml      = false ;
00259 
00260     // hope there is a . before fed or xml
00261     if ( filename[nbcar_filename-4] != '.' )
00262         {
00263         G.Out(pdGendoc,"exit Federation::Federation on exception CouldNotOpenFED");
00264         throw CouldNotOpenFED("Incorrect FED file name, cannot find "
00265          "extension (character '.' is missing [or not in reverse 4th place])");
00266         }
00267 
00268     string extension = filename.substr(nbcar_filename-3,3) ;
00269     D.Out(pdTrace,"filename is: %s (extension is <%s>",filename.c_str(),extension.c_str());
00270     if ( !strcasecmp(extension.c_str(),"fed") )
00271         {
00272         is_a_fed = true ;
00273         D.Out(pdTrace, "Trying to use .fed file");
00274         }
00275     else if  ( !strcasecmp(extension.c_str(),"xml") )
00276         {
00277         is_an_xml = true ;
00278         D.Out(pdTrace, "Trying to use .xml file");
00279         }
00280     else {
00281         G.Out(pdGendoc,"exit Federation::Federation on exception CouldNotOpenFED");
00282         throw CouldNotOpenFED("Incorrect FED file name : nor .fed nor .xml file");
00283     }
00284 
00285     std::ifstream fedFile(filename.c_str());
00286 
00287     if (fedFile.is_open())
00288         {
00289         fedFile.close();
00290         if ( is_a_fed )
00291             {
00292             // parse FED file and show the parse on stdout if verboseLevel>=2
00293         int err = fedparser::build(filename.c_str(), root, (verboseLevel>=2));
00294         if (err != 0 )
00295                 {
00296                 G.Out(pdGendoc,"exit Federation::Federation on exception ErrorReadingFED");
00297                 throw ErrorReadingFED("fed parser found error in FED file");
00298             }
00299 
00300             // Retrieve the FED file last modification time(for Audit)
00301             STAT_STRUCT StatBuffer ;
00302             #if defined(_WIN32) && _MSC_VER >= 1400
00303             char MTimeBuffer[26];
00304             #else
00305             char *MTimeBuffer ;
00306             #endif
00307 
00308             if (STAT_FUNCTION(filename.c_str(), &StatBuffer) == 0) {
00309             #if defined(_WIN32) && _MSC_VER >= 1400
00310                 ctime_s(&MTimeBuffer[0],26,&StatBuffer.st_mtime);
00311             #else
00312                 MTimeBuffer = ctime(&StatBuffer.st_mtime);
00313             #endif
00314                 MTimeBuffer[strlen(MTimeBuffer) - 1] = 0 ; // Remove trailing \n
00315                 server->audit << "(Last modified " << MTimeBuffer << ")" ;
00316             }
00317             else
00318                 server->audit << "(could not retrieve last modif time, errno "
00319                   << errno << ")." ;
00320             }
00321         else if ( is_an_xml )
00322             {
00323             if (XmlParser::exists()) {
00324                 XmlParser *parser = new XmlParser(root);
00325                 server->audit << ", XML File : " << filename.c_str() ;
00326 
00327                 try {
00328                     parser->parse(filename);
00329                 }
00330                 catch (Exception *e) {
00331                     delete parser ;
00332                     delete server ;
00333                     server = NULL ;
00334                     delete root ;
00335                     root = NULL ;
00336                     throw e ;
00337                 }
00338                 delete parser ;
00339             }
00340             else {
00341                 cout << "nor fed nor xml" << endl ;
00342                 G.Out(pdGendoc,"exit Federation::Federation on exception CouldNotOpenFED");
00343         throw CouldNotOpenFED("Incorrect FED file name : nor fed nor xml");
00344         }
00345         }
00346     }
00347 
00348     G.Out(pdGendoc,"exit Federation::Federation");
00349 
00350 }
00351 
00352 // ----------------------------------------------------------------------------
00353 // Destructor
00354 Federation::~Federation()
00355 {
00356     D.Out(pdInit, "Destroying Federation %d...", handle);
00357 
00358     // If there are Federates, delete them all!
00359 //     for (list<Federate *>::const_iterator i = begin(); i != end(); i++) {
00360 //         delete(*i);
00361 //     }
00362 //     clear();
00363 
00364     // Free local allocations
00365     delete root ;
00366     delete server ;
00367 
00368 #ifdef FEDERATION_USES_MULTICAST
00369     FermerConnexion(mc_link);
00370     delete mc_link ;
00371 #endif
00372 
00373 }
00374 
00375 // ----------------------------------------------------------------------------
00377 int
00378 Federation::getNbFederates() const
00379 {
00380     return federates.size();
00381 }
00382 
00383 // ----------------------------------------------------------------------------
00385 bool
00386 Federation::isSynchronizing() const
00387 {
00388     return !synchronizationLabels.empty();
00389 }
00390 
00391 // ----------------------------------------------------------------------------
00393 Handle
00394 Federation::getHandle() const
00395 {
00396     return handle ;
00397 }
00398 
00399 // ----------------------------------------------------------------------------
00401 const char *
00402 Federation::getName() const
00403 {
00404     return name.c_str() ;
00405 }
00406 
00407 // ----------------------------------------------------------------------------
00409 int
00410 Federation::getNbRegulators() const
00411 {
00412     return regulators.size();
00413 }
00414 
00415 // ----------------------------------------------------------------------------
00417 const char *
00418 Federation::getFEDid() const
00419 {
00420     return FEDid.c_str() ;
00421 }
00422 
00423 // ----------------------------------------------------------------------------
00429 FederateHandle
00430 Federation::add(const char *federate_name, SocketTCP *tcp_link)
00431     throw (FederateAlreadyExecutionMember, MemoryExhausted, RTIinternalError)
00432 {
00433     if (federate_name == 0) {
00434         D.Out(pdExcept, "Tried to add a NULL named federate.");
00435         throw RTIinternalError("Tried to add NULL federate to federation.");
00436     }
00437 
00438     try {
00439         getFederate(federate_name);
00440         throw FederateAlreadyExecutionMember("");
00441     }
00442     catch (FederateNotExecutionMember &e) {
00443         // Nothing to do.
00444     }
00445 
00446     FederateHandle federate_handle = federateHandles.provide();
00447     federates.push_back(Federate(federate_name, federate_handle));
00448     D.Out(pdInit, "Federate %d joined Federation %d.", federate_handle, handle);
00449 
00450     // Send, to the newly added federate, a Null message from each regulating
00451     // federate (i) with their logical time h(i). This permits to calculate
00452     // its LBTS.
00453     NM_Message_Null nullMessage;
00454     NM_Announce_Synchronization_Point ASPMessage;
00455     try {
00456     std::vector<LBTS::FederateClock> v ;
00457     regulators.get(v);
00458 
00459         for (unsigned int i = 0 ; i < v.size(); ++i) {
00460             nullMessage.federation = handle ;
00461             nullMessage.federate = v[i].first ;
00462             nullMessage.setDate(v[i].second);
00463             D.Out(pdTerm,
00464           "Sending NULL message(type %d) from %d to new federate.",
00465                   nullMessage.getType(), nullMessage.federate);
00466 
00467             nullMessage.send(tcp_link,NM_msgBufSend);
00468         }
00469 
00470         // If federation is synchronizing, put federate in same state.
00471         if (isSynchronizing()) {
00472             ASPMessage.federate = federate_handle ;
00473             ASPMessage.federation = handle ;
00474 
00475             std::map<const char *, const char *>::const_iterator i ;
00476             i = synchronizationLabels.begin();
00477             for (; i != synchronizationLabels.end(); i++) {
00478                 ASPMessage.setLabel((*i).first);
00479                 ASPMessage.setTag((*i).second);
00480                 D.Out(pdTerm, "Sending synchronization message %s (type %d)"
00481                       " to the new Federate.", (*i).first, ASPMessage.getType());
00482 
00483                 ASPMessage.send(tcp_link,NM_msgBufSend);
00484                 federates.back().addSynchronizationLabel((*i).first);
00485             }
00486         }
00487     }
00488     catch (NetworkError) {
00489         throw RTIinternalError("Network Error while initializing federate.");
00490     }
00491 
00492     return federate_handle ;
00493 }
00494 
00495 // ----------------------------------------------------------------------------
00496 // Set Federate's attribute IsConstrained to true.
00499 void
00500 Federation::addConstrained(FederateHandle federate_handle)
00501     throw (FederateNotExecutionMember,
00502            SaveInProgress,
00503            RestoreInProgress,
00504            RTIinternalError)
00505 {
00506     // It may throw FederateNotExecutionMember
00507     Federate &federate = getFederate(federate_handle);
00508 
00509     if (federate.isConstrained()) {
00510         D.Out(pdExcept, "Federate %d already constrained.", federate_handle);
00511         throw RTIinternalError("Time Constrained already enabled.");
00512     }
00513 
00514     federate.setConstrained(true);
00515     D.Out(pdTerm, "Federation %d: Federate %d is now constrained.",
00516           handle, federate_handle);
00517 }
00518 
00519 // ----------------------------------------------------------------------------
00520 // Set Class Relevance Advisory Switch
00521 void
00522 Federation::setClassRelevanceAdvisorySwitch(FederateHandle federate_handle)
00523     throw (FederateNotExecutionMember,
00524            SaveInProgress,
00525            RestoreInProgress,
00526            RTIinternalError)
00527 {
00528     // It may throw FederateNotExecutionMember
00529     Federate &federate = getFederate(federate_handle);
00530 
00531     if (federate.isClassRelevanceAdvisorySwitch()) {
00532         D.Out(pdExcept, "Federate %d already set CRA switch.", federate_handle);
00533         throw RTIinternalError("CRA switch already enabled.");
00534     }
00535 
00536     federate.setClassRelevanceAdvisorySwitch(true);
00537     D.Out(pdTerm, "Federation %d: Federate %d sets CRA switch.",
00538               handle, federate_handle);
00539 }
00540 
00541 // ----------------------------------------------------------------------------
00542 // Set Interaction Relevance Advisory Switch
00543 void
00544 Federation::setInteractionRelevanceAdvisorySwitch(FederateHandle federate_handle)
00545     throw (FederateNotExecutionMember,
00546            SaveInProgress,
00547            RestoreInProgress,
00548            RTIinternalError)
00549 {
00550     // It may throw FederateNotExecutionMember
00551     Federate &federate = getFederate(federate_handle);
00552 
00553     if (federate.isInteractionRelevanceAdvisorySwitch()) {
00554         D.Out(pdExcept, "Federate %d already set IRA switch.", federate_handle);
00555         throw RTIinternalError("IRA switch already enabled.");
00556     }
00557 
00558     federate.setInteractionRelevanceAdvisorySwitch(true);
00559     D.Out(pdTerm, "Federation %d: Federate %d sets IRA switch.",
00560               handle, federate_handle);
00561 }
00562 
00563 // ----------------------------------------------------------------------------
00564 // Set Attribute Relevance Advisory Switch
00565 void
00566 Federation::setAttributeRelevanceAdvisorySwitch(FederateHandle federate_handle)
00567     throw (FederateNotExecutionMember,
00568            SaveInProgress,
00569            RestoreInProgress,
00570            RTIinternalError)
00571 {
00572     // It may throw FederateNotExecutionMember
00573     Federate &federate = getFederate(federate_handle);
00574 
00575     if (federate.isAttributeRelevanceAdvisorySwitch()) {
00576         D.Out(pdExcept, "Federate %d already set ARA switch.", federate_handle);
00577         throw RTIinternalError("ARA switch already enabled.");
00578     }
00579 
00580     federate.setAttributeRelevanceAdvisorySwitch(true);
00581     D.Out(pdTerm, "Federation %d: Federate %d sets ARA switch.",
00582               handle, federate_handle);
00583 }
00584 
00585 // ----------------------------------------------------------------------------
00586 // Set Attribute Scope Advisory Switch
00587 void
00588 Federation::setAttributeScopeAdvisorySwitch(FederateHandle federate_handle)
00589     throw (FederateNotExecutionMember,
00590            SaveInProgress,
00591            RestoreInProgress,
00592            RTIinternalError)
00593 {
00594     // It may throw FederateNotExecutionMember
00595     Federate &federate = getFederate(federate_handle);
00596 
00597     if (federate.isAttributeScopeAdvisorySwitch()) {
00598         D.Out(pdExcept, "Federate %d already set ASA switch.", federate_handle);
00599         throw RTIinternalError("ASA switch already enabled.");
00600     }
00601 
00602     federate.setAttributeScopeAdvisorySwitch(true);
00603     D.Out(pdTerm, "Federation %d: Federate %d sets ASA switch.",
00604               handle, federate_handle);
00605 }
00606 
00607 // ----------------------------------------------------------------------------
00608 // Clear Class Relevance Advisory Switch
00609 void
00610 Federation::unsetClassRelevanceAdvisorySwitch(FederateHandle federate_handle)
00611     throw (FederateNotExecutionMember,
00612            SaveInProgress,
00613            RestoreInProgress,
00614            RTIinternalError)
00615 {
00616     // It may throw FederateNotExecutionMember
00617     Federate &federate = getFederate(federate_handle);
00618 
00619     if (!federate.isClassRelevanceAdvisorySwitch()) {
00620         D.Out(pdExcept, "Federate %d did not set CRA switch.", federate_handle);
00621         throw RTIinternalError("CRA switch not enabled.");
00622     }
00623 
00624     federate.setClassRelevanceAdvisorySwitch(false);
00625     D.Out(pdTerm, "Federation %d: Federate %d clears CRA switch.",
00626               handle, federate_handle);
00627 }
00628 
00629 // ----------------------------------------------------------------------------
00630 // Clear Interaction Relevance Advisory Switch
00631 void
00632 Federation::unsetInteractionRelevanceAdvisorySwitch(FederateHandle federate_handle)
00633     throw (FederateNotExecutionMember,
00634            SaveInProgress,
00635            RestoreInProgress,
00636            RTIinternalError)
00637 {
00638     // It may throw FederateNotExecutionMember
00639     Federate &federate = getFederate(federate_handle);
00640 
00641     if (!federate.isInteractionRelevanceAdvisorySwitch()) {
00642         D.Out(pdExcept, "Federate %d did not set IRA switch.", federate_handle);
00643         throw RTIinternalError("IRA switch not enabled.");
00644     }
00645 
00646     federate.setInteractionRelevanceAdvisorySwitch(false);
00647     D.Out(pdTerm, "Federation %d: Federate %d clears IRA switch.",
00648               handle, federate_handle);
00649 }
00650 
00651 // ----------------------------------------------------------------------------
00652 // Clear Attribute Relevance Advisory Switch
00653 void
00654 Federation::unsetAttributeRelevanceAdvisorySwitch(FederateHandle federate_handle)
00655     throw (FederateNotExecutionMember,
00656            SaveInProgress,
00657            RestoreInProgress,
00658            RTIinternalError)
00659 {
00660     // It may throw FederateNotExecutionMember
00661     Federate &federate = getFederate(federate_handle);
00662 
00663     if (!federate.isAttributeRelevanceAdvisorySwitch()) {
00664         D.Out(pdExcept, "Federate %d did not set ARA switch.", federate_handle);
00665         throw RTIinternalError("ARA switch not enabled.");
00666     }
00667 
00668     federate.setAttributeRelevanceAdvisorySwitch(false);
00669     D.Out(pdTerm, "Federation %d: Federate %d clears ARA switch.",
00670               handle, federate_handle);
00671 }
00672 
00673 // ----------------------------------------------------------------------------
00674 //  Clear Attribute Scope Advisory Switch
00675 void
00676 Federation::unsetAttributeScopeAdvisorySwitch(FederateHandle federate_handle)
00677     throw (FederateNotExecutionMember,
00678            SaveInProgress,
00679            RestoreInProgress,
00680            RTIinternalError)
00681 {
00682     // It may throw FederateNotExecutionMember
00683     Federate &federate = getFederate(federate_handle);
00684 
00685     if (!federate.isAttributeScopeAdvisorySwitch()) {
00686         D.Out(pdExcept, "Federate %d did not set ASA switch.", federate_handle);
00687         throw RTIinternalError("ASA switch not enabled.");
00688     }
00689 
00690     federate.setAttributeScopeAdvisorySwitch(false);
00691     D.Out(pdTerm, "Federation %d: Federate %d clears ASA switch.",
00692               handle, federate_handle);
00693 }
00694 
00695 // ----------------------------------------------------------------------------
00697 
00700 void
00701 Federation::addRegulator(FederateHandle federate_handle, FederationTime time)
00702     throw (FederateNotExecutionMember,
00703            SaveInProgress,
00704            RestoreInProgress,
00705            RTIinternalError)
00706 {
00707     // It may throw FederateNotExecutionMember
00708     Federate &federate = getFederate(federate_handle);
00709 
00710     // It may throw RTIinternalError if Federate was not regulators.
00711     regulators.insert(federate_handle, time);
00712     federate.setRegulator(true);
00713 
00714     D.Out(pdTerm, "Federation %d: Federate %d is now a regulator(Time=%f).",
00715           handle, federate_handle, time.getTime());
00716 
00717     NM_Set_Time_Regulating msg ;
00718     msg.exception = e_NO_EXCEPTION ;
00719     msg.federation = handle ;
00720     msg.federate = federate_handle ;
00721     msg.regulatorOn();
00722     msg.setDate(time);
00723 
00724     this->broadcastAnyMessage(&msg, 0);
00725 }
00726 
00727 // ----------------------------------------------------------------------------
00729 void
00730 Federation::broadcastAnyMessage(NetworkMessage *msg,
00731                                 FederateHandle except_federate)
00732 {
00733     Socket *socket = NULL ;
00734 
00735     // Broadcast the message 'msg' to all Federates in the Federation
00736     // except to Federate whose Handle is 'Except_Federate'.
00737     for (FederateList::const_iterator i = federates.begin(); i != federates.end(); ++i) {
00738         if (i->getHandle() != except_federate) {
00739             try {
00740 #ifdef HLA_USES_UDP
00741                 socket = server->getSocketLink(i->getHandle(), BEST_EFFORT);
00742 #else
00743                 socket = server->getSocketLink(i->getHandle());
00744 #endif
00745                 msg->send(socket,NM_msgBufSend);
00746             }
00747             catch (RTIinternalError &e) {
00748                 D[pdExcept] << "Reference to a killed Federate while "
00749                             << "broadcasting." << endl ;
00750             }
00751             catch (NetworkError &e) {
00752                 D.Out(pdExcept, "Network error while broadcasting, ignoring.");
00753             }
00754         }
00755     }
00756 
00757     // BUG: If except = 0, could use Multicast.
00758 }
00759 
00760 // ----------------------------------------------------------------------------
00762 void
00763 Federation::broadcastSomeMessage(NetworkMessage *msg,
00764                                 FederateHandle except_federate,
00765                                 std::vector <FederateHandle> &fede_array,
00766                                 int nbfed)
00767 {
00768     int ifed ;
00769     Socket *socket = NULL ;
00770 
00771     if ( fede_array.size() != 0 || nbfed == 0)
00772         {
00773         // Broadcast the message 'msg' to some Federates (done in fede_array)
00774         // in the Federation
00775         // except to Federate whose Handle is 'Except_Federate'.
00776         for (FederateList::const_iterator i = federates.begin(); i != federates.end(); ++i)
00777             {
00778             if (i->getHandle() != except_federate)
00779                 {
00780                 ifed = 0 ;
00781                 while ( ifed < nbfed )
00782                     {
00783                     if ( i->getHandle() == fede_array[ifed] )
00784                         // Federate i has to be informed because into fede_array
00785                         {
00786                         try
00787                             {
00788 #ifdef HLA_USES_UDP
00789                             socket = server->getSocketLink(i->getHandle(), BEST_EFFORT);
00790 #else
00791                             socket = server->getSocketLink(i->getHandle());
00792 #endif
00793                             msg->send(socket,NM_msgBufSend);
00794                             }
00795                         catch (RTIinternalError &e)
00796                             {
00797                             D[pdExcept] << "Reference to a killed Federate while "
00798                                         << "broadcasting." << endl ;
00799                             }
00800                         catch (NetworkError &e)
00801                             {
00802                             D.Out(pdExcept, "Network error while broadcasting, ignoring.");
00803                             }
00804                         }
00805                     ifed++;
00806                     }
00807                 }
00808             }
00809         }
00810 
00811     // BUG: If except = 0, could use Multicast.
00812 }
00813 
00814 // ----------------------------------------------------------------------------
00816 void
00817 Federation::broadcastInteraction(FederateHandle federate_handle,
00818                                  InteractionClassHandle interaction,
00819                                  std::vector <ParameterHandle> &parameter_handles,
00820                                  std::vector <ParameterValue_t> &parameter_values,
00821                                  UShort list_size,
00822                                  FederationTime time,
00823                  RegionHandle region_handle,
00824                                  const char *tag)
00825     throw (FederateNotExecutionMember,
00826            FederateNotPublishing,
00827            InteractionClassNotDefined,
00828            InteractionParameterNotDefined,
00829            SaveInProgress,
00830            RestoreInProgress,
00831            RTIinternalError)
00832 {
00833 
00834     G.Out(pdGendoc,"enter Federation::broadcastInteraction with time");
00835 
00836     // It may throw FederateNotExecutionMember.
00837     this->check(federate_handle);
00838 
00839     const RTIRegion *region = 0 ;
00840     if (region_handle != 0)
00841     region = root->getRegion(region_handle);
00842 
00843     root->Interactions->broadcastInteraction(federate_handle,
00844                                              interaction,
00845                                              parameter_handles,
00846                                              parameter_values,
00847                                              list_size,
00848                                              time,
00849                          region,
00850                                              tag);
00851     D.Out(pdRequest, "Federation %d: Broadcasted Interaction %d from Federate "
00852           "%d nb params %d.", handle, interaction, federate_handle, list_size);
00853     for (int i=0 ; i < list_size ; i++)
00854         D.Out(pdRequest,
00855               " Param %d Value %s",
00856               parameter_handles[i],
00857               parameter_values[i].c_str());
00858 
00859     G.Out(pdGendoc,"exit Federation::broadcastInteraction with time");
00860 
00861 }
00862 
00863 // ----------------------------------------------------------------------------
00865 void
00866 Federation::broadcastInteraction(FederateHandle federate_handle,
00867                                  InteractionClassHandle interaction,
00868                                  std::vector <ParameterHandle> &parameter_handles,
00869                                  std::vector <ParameterValue_t> &parameter_values,
00870                                  UShort list_size,
00871                  RegionHandle region_handle,
00872                                  const char *tag)
00873     throw (FederateNotExecutionMember,
00874            FederateNotPublishing,
00875            InteractionClassNotDefined,
00876            InteractionParameterNotDefined,
00877            SaveInProgress,
00878            RestoreInProgress,
00879            RTIinternalError)
00880 {
00881 
00882     G.Out(pdGendoc,"enter Federation::broadcastInteraction without time");
00883 
00884     // It may throw FederateNotExecutionMember.
00885     this->check(federate_handle);
00886 
00887     const RTIRegion *region = 0 ;
00888     if (region_handle != 0)
00889     region = root->getRegion(region_handle);
00890 
00891     root->Interactions->broadcastInteraction(federate_handle,
00892                                              interaction,
00893                                              parameter_handles,
00894                                              parameter_values,
00895                                              list_size,
00896                          region,
00897                                              tag);
00898     D.Out(pdRequest, "Federation %d: Broadcasted Interaction %d from Federate "
00899           "%d nb params %d.", handle, interaction, federate_handle, list_size);
00900     for (int i=0 ; i < list_size ; i++)
00901         D.Out(pdRequest,
00902               " Param %d Value %s",
00903               parameter_handles[i],
00904               parameter_values[i].c_str());
00905 
00906     G.Out(pdGendoc,"exit Federation::broadcastInteraction without time");
00907 
00908 }
00909 
00910 // ----------------------------------------------------------------------------
00917 void
00918 Federation::deleteObject(FederateHandle federate,
00919                          ObjectHandle id,
00920              FederationTime theTime,
00921                          const char *tag)
00922     throw (FederateNotExecutionMember,
00923            DeletePrivilegeNotHeld,
00924            ObjectNotKnown,
00925            SaveInProgress,
00926            RestoreInProgress,
00927        InvalidFederationTime,
00928            RTIinternalError)
00929 {
00930     // It may throw FederateNotExecutionMember.
00931     this->check(federate);
00932 
00933     D.Out(pdRegister, "Federation %d: Federate %d destroys object %d.",
00934           this->handle, federate, id);
00935 
00936     root->deleteObjectInstance(federate, id, theTime, tag);
00937     objectHandles.free(id);
00938 }
00939 // ----------------------------------------------------------------------------
00945 void
00946 Federation::deleteObject(FederateHandle federate,
00947                          ObjectHandle id,
00948                          const char *tag)
00949     throw (FederateNotExecutionMember,
00950            DeletePrivilegeNotHeld,
00951            ObjectNotKnown,
00952            SaveInProgress,
00953            RestoreInProgress,
00954            RTIinternalError)
00955 {
00956     // It may throw FederateNotExecutionMember.
00957     this->check(federate);
00958 
00959     D.Out(pdRegister, "Federation %d: Federate %d destroys object %d.",
00960           this->handle, federate, id);
00961 
00962     root->deleteObjectInstance(federate, id, tag);
00963     objectHandles.free(id);
00964 }
00965 
00966 // ----------------------------------------------------------------------------
00968 void
00969 Federation::registerSynchronization(FederateHandle federate,
00970                                     const char *label,
00971                                     const char *tag)
00972     throw (FederateNotExecutionMember,
00973            FederationAlreadyPaused,
00974            SaveInProgress,
00975            RestoreInProgress,
00976            RTIinternalError)
00977 {
00978 
00979     G.Out(pdGendoc,"enter Federation::registerSynchronization for all federates");
00980 
00981     this->check(federate); // It may throw FederateNotExecutionMember.
00982 
00983     if (label == NULL )
00984         throw RTIinternalError("Bad pause label(null).");
00985 
00986     // Verify label does not already exists
00987     std::map<const char *, const char *>::const_iterator i ;
00988     i = synchronizationLabels.begin();
00989     for (; i != synchronizationLabels.end(); i++) {
00990         if (!strcmp((*i).first, label)) {
00991             throw FederationAlreadyPaused(""); // Label already pending.
00992         }
00993     }
00994 
00995     // If not already in pending labels, insert to list.
00996     synchronizationLabels.insert(pair<const char *, const char *>(strdup(label),
00997                                                                   strdup(tag)));
00998 
00999     // Add label to each federate (may throw RTIinternalError).
01000     FederateList::iterator j ;
01001     for (j = federates.begin(); j != federates.end(); ++j) {
01002         j->addSynchronizationLabel(label);
01003     }
01004 
01005     D[pdTerm] << "Federation " << handle << " is now synchronizing for label "
01006               << label << endl ;
01007 
01008     G.Out(pdGendoc,"exit  Federation::registerSynchronization for all federates");
01009 
01010 
01011 }
01012 
01013 // ----------------------------------------------------------------------------
01015 void
01016 Federation::registerSynchronization(FederateHandle federate,
01017                                     const char *label,
01018                                     const char *tag,
01019                                     unsigned short federate_setSize,
01020                                     std::vector <FederateHandle> &federate_set)
01021     throw (FederateNotExecutionMember,
01022            FederationAlreadyPaused,
01023            SaveInProgress,
01024            RestoreInProgress,
01025            RTIinternalError)
01026 {
01027 
01028     G.Out(pdGendoc,"enter Federation::registerSynchronization for federate set");
01029 
01030     this->check(federate); // It may throw FederateNotExecutionMember.
01031 
01032     if (label == NULL)
01033         throw RTIinternalError("Bad pause label(null).");
01034 
01035     // Verify label does not already exists
01036     std::map<const char *, const char *>::const_iterator i ;
01037     i = synchronizationLabels.begin();
01038     for (; i != synchronizationLabels.end(); i++) {
01039         if (!strcmp((*i).first, label)) {
01040             throw FederationAlreadyPaused(""); // Label already pending.
01041         }
01042     }
01043 
01044     // If not already in pending labels, insert to list.
01045     synchronizationLabels.insert(pair<const char *, const char *>(strdup(label),
01046                                                                   strdup(tag)));
01047 
01048     // Add label to each federate into the set only (may throw RTIinternalError).
01049     FederateList::iterator j ;
01050     for (int i=0 ; i < federate_setSize  ;i++ )
01051         {
01052         for (j = federates.begin(); j != federates.end(); ++j)
01053             {
01054             if ( (federate_set[i] == j->getHandle()) || (federate == j->getHandle()) )
01055                              j->addSynchronizationLabel(label);
01056             }
01057         }
01058 
01059     D[pdTerm] << "Federation " << handle << " is now synchronizing for label "
01060               << label << endl ;
01061 
01062     G.Out(pdGendoc,"exit  Federation::registerSynchronization for federate set");
01063 
01064 
01065 }
01066 
01067 // ----------------------------------------------------------------------------
01071 void
01072 Federation::broadcastSynchronization(FederateHandle federate,
01073                                      const char *label,
01074                                      const char *tag)
01075     throw (RTIinternalError)
01076 {
01077 
01078     G.Out(pdGendoc,"enter Federation::broadcastSynchronization");
01079 
01080     this->check(federate); // It may throw FederateNotExecutionMember.
01081 
01082     if (label == NULL)
01083         throw RTIinternalError("Bad pause label(null).");
01084 
01085     // broadcast announceSynchronizationPoint() to all federates in federation.
01086     NM_Announce_Synchronization_Point msg ;
01087     msg.federate = federate ;
01088     msg.federation = handle ;
01089     msg.setLabel(label);
01090     msg.setTag(tag);
01091 
01092     G.Out(pdGendoc,"      broadcastSynchronization is calling broadcastAnyMessage for all federates");
01093 
01094     broadcastAnyMessage(&msg, 0);
01095 
01096     G.Out(pdGendoc,"exit  Federation::broadcastSynchronization");
01097 
01098 }
01099 
01100 // ----------------------------------------------------------------------------
01104 void
01105 Federation::broadcastSynchronization(FederateHandle federate,
01106                                      const char *label,
01107                                      const char *tag,
01108                                      unsigned short federate_setSize,
01109                                      std::vector <FederateHandle> &federate_set)
01110     throw (RTIinternalError)
01111 {
01112 
01113     G.Out(pdGendoc,"enter Federation::broadcastSynchronization to some federates");
01114 
01115     this->check(federate); // It may throw FederateNotExecutionMember.
01116 
01117     if (label == NULL)
01118         throw RTIinternalError("Bad pause label(null or too long).");
01119 
01120     // broadcast announceSynchronizationPoint() to all federates in federation.
01121     NM_Announce_Synchronization_Point msg ;
01122     msg.federate = federate ;
01123     msg.federation = handle ;
01124     msg.setLabel(label);
01125     msg.setTag(tag);
01126 
01127     G.Out(pdGendoc,"      broadcastSynchronization is calling broadcastSomeMessage");
01128 
01129     broadcastSomeMessage(&msg, 0, federate_set, (unsigned short)federate_setSize);
01130 
01131     G.Out(pdGendoc,"exit  Federation::broadcastSynchronization to some federates");
01132 
01133 }
01134 
01135 
01136 // ----------------------------------------------------------------------------
01138 
01141 void
01142 Federation::requestFederationSave(FederateHandle the_federate,
01143                                   const char *the_label,
01144                                   FederationTime time )
01145     throw (FederateNotExecutionMember, SaveInProgress)
01146 {
01147     G.Out(pdGendoc,"enter Federation::requestFederationSave with time");
01148 
01149     check(the_federate);
01150 
01151     if (saveInProgress)
01152         throw SaveInProgress("Already in saving state.");
01153 
01154     for (FederateList::iterator j = federates.begin(); j != federates.end(); ++j) {
01155         j->setSaving(true);
01156     }
01157 
01158     saveStatus = true ;
01159     saveInProgress = true ;
01160     saveLabel = the_label ;
01161 
01162     NM_Initiate_Federate_Save msg ;
01163     msg.federate = the_federate ;
01164     msg.federation = handle ;
01165     msg.setLabel(the_label);
01166     // timed message
01167     msg.setDate(time);
01168 
01169     G.Out(pdGendoc,"      requestFederationSave====>broadcast I_F_S to all");
01170 
01171     broadcastAnyMessage(&msg, 0);
01172 
01173     G.Out(pdGendoc,"exit  Federation::requestFederationSave with time");
01174 }
01175 
01176 // ----------------------------------------------------------------------------
01178 
01181 void
01182 Federation::requestFederationSave(FederateHandle the_federate,
01183                                   const char *the_label)
01184     throw (FederateNotExecutionMember, SaveInProgress)
01185 {
01186     G.Out(pdGendoc,"enter Federation::requestFederationSave without time");
01187 
01188     check(the_federate);
01189 
01190     if (saveInProgress)
01191         throw SaveInProgress("Already in saving state.");
01192 
01193     for (FederateList::iterator j = federates.begin(); j != federates.end(); ++j) {
01194         j->setSaving(true);
01195     }
01196 
01197     saveStatus = true ;
01198     saveInProgress = true ;
01199     saveLabel = the_label ;
01200 
01201     NM_Initiate_Federate_Save msg ;
01202     msg.federate = the_federate ;
01203     msg.federation = handle ;
01204     msg.setLabel(the_label);
01205 
01206     G.Out(pdGendoc,"                  requestFederationSave====>broadcast I_F_S"
01207                    " to all");
01208 
01209     broadcastAnyMessage(&msg, 0);
01210 
01211     G.Out(pdGendoc,"exit  Federation::requestFederationSave without time");
01212 }
01213 // ----------------------------------------------------------------------------
01218 void
01219 Federation::federateSaveBegun(FederateHandle the_federate)
01220     throw (FederateNotExecutionMember)
01221 {
01222     G.Out(pdGendoc,"enter Federation::federateSaveBegun");
01223     check(the_federate);
01224     G.Out(pdGendoc,"exit  Federation::federateSaveBegun");
01225 }
01226 
01227 // ----------------------------------------------------------------------------
01229 void
01230 Federation::federateSaveStatus(FederateHandle the_federate, bool the_status)
01231     throw (FederateNotExecutionMember)
01232 {
01233     G.Out(pdGendoc,"enter Federation::federateSaveStatus");
01234 
01235     Federate &federate = getFederate(the_federate);
01236     federate.setSaving(false);
01237 
01238     if (!the_status)
01239         saveStatus = false ;
01240 
01241     // Verify that all federates save ended (complete or not).
01242     for (FederateList::iterator j = federates.begin(); j != federates.end(); ++j) {
01243         if (j->isSaving())
01244             {
01245             G.Out(pdGendoc,"exit  Federation::federateSaveStatus one federate has not save ended");
01246             return ;
01247             }
01248     }
01249 
01250     // Save RTIG Data for future restoration.
01251     if (saveStatus) {
01252         saveStatus = saveXmlData();
01253     }
01254 
01255     // Send end save message.
01256     std::auto_ptr<NetworkMessage> msg(NM_Factory::create(saveStatus ? NetworkMessage::FEDERATION_SAVED : NetworkMessage::FEDERATION_NOT_SAVED )) ;
01257 
01258     msg->federate = the_federate ;
01259     msg->federation = handle ;
01260 
01261     broadcastAnyMessage(msg.get(), 0);
01262 
01263     G.Out(pdGendoc,"            =======> broadcast F_S or F_N_S");
01264 
01265     // Reinitialize state.
01266     saveStatus = true ;
01267     saveInProgress = false ;
01268 
01269     G.Out(pdGendoc,"exit  Federation::federateSaveStatus");
01270 }
01271 
01272 // ----------------------------------------------------------------------------
01274 void
01275 Federation::requestFederationRestore(FederateHandle the_federate,
01276                                      const char *the_label)
01277     throw (FederateNotExecutionMember)
01278 {
01279     G.Out(pdGendoc,"enter Federation::requestFederationRestore");
01280 
01281     check(the_federate);
01282 
01283     if (restoreInProgress)
01284         throw RestoreInProgress("Already in restoring state.");
01285 
01286     Socket * socket ;
01287     NetworkMessage *msg;
01288 
01289 
01290     // Informs sending federate of success/failure in restoring.
01291     // At this point, only verify that file is present.
01292     bool success = true ;
01293 #ifdef HAVE_XML
01294     string filename = string(name) + "_" + string(the_label) + ".xcs" ;
01295     doc = xmlParseFile(filename.c_str());
01296 
01297     // Did libXML manage to parse the file ?
01298     if (doc == 0) {
01299         cerr << "XML restore file not parsed successfully" << endl ;
01300         xmlFreeDoc(doc);
01301         success = false ;
01302     }
01303     if (success) {
01304         success = restoreXmlData();
01305     }
01306 #else
01307     success = false ;
01308 #endif // HAVE_XML
01309 
01310 // JYR Note : forcing success to true to skip xmlParseFile (not compliant ?)
01311     success = true ;
01312 
01313     if (success) {
01314         msg = NM_Factory::create(NetworkMessage::REQUEST_FEDERATION_RESTORE_SUCCEEDED);
01315     } else {
01316         msg = NM_Factory::create(NetworkMessage::REQUEST_FEDERATION_RESTORE_FAILED);
01317     }
01318 
01319     msg->federate = the_federate ;
01320     msg->federation = handle ;
01321     msg->setLabel(the_label);
01322 
01323     socket = server->getSocketLink(msg->federate);
01324 
01325     if (success)
01326        G.Out(pdGendoc,"             =====> send message R_F_R_S to RTIA");
01327     else
01328        G.Out(pdGendoc,"             =====> send message R_F_R_F to RTIA");
01329 
01330     msg->send(socket,NM_msgBufSend);
01331     delete msg ;
01332 
01333     // Reading file failed: not restoring !
01334     if (!success)
01335         {
01336         G.Out(pdGendoc,"exit  Federation::requestFederationRestore on success false");
01337         return ;
01338         }
01339 
01340     // Otherwise...
01341     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
01342         i->setRestoring(true);
01343     }
01344     restoreStatus = true ;
01345     restoreInProgress = true ;
01346 
01347     // Informs federates a new restore is being done.
01348     msg = NM_Factory::create(NetworkMessage::FEDERATION_RESTORE_BEGUN);
01349     msg->federate = the_federate ;
01350     msg->federation = handle ;
01351 
01352     G.Out(pdGendoc,"             =====> broadcast message F_R_B");
01353 
01354     broadcastAnyMessage(msg, 0);
01355     delete msg ;
01356 
01357     // For each federate, send an initiateFederateRestore with correct handle.
01358     msg = NM_Factory::create(NetworkMessage::INITIATE_FEDERATE_RESTORE);
01359     msg->federation = handle ;
01360     msg->setLabel(the_label);
01361 
01362     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
01363         msg->federate = i->getHandle();
01364 
01365         // send message.
01366         socket = server->getSocketLink(msg->federate);
01367         G.Out(pdGendoc,"             =====> send message I_F_R to federate %d",msg->federate);
01368         msg->send(socket,NM_msgBufSend);
01369     }
01370     delete msg;
01371     G.Out(pdGendoc,"exit  Federation::requestFederationRestore");
01372 }
01373 
01374 // ----------------------------------------------------------------------------
01376 
01379 void
01380 Federation::federateRestoreStatus(FederateHandle the_federate,
01381                                   bool the_status)
01382     throw (FederateNotExecutionMember)
01383 {
01384     G.Out(pdGendoc,"enter Federation::federateRestoreStatus");
01385     Federate &federate = getFederate(the_federate);
01386     federate.setRestoring(false);
01387 
01388     if (!the_status)
01389         restoreStatus = false ;
01390 
01391     // Verify that all federates save ended (complete or not).
01392     for (FederateList::iterator j = federates.begin(); j != federates.end(); ++j) {
01393         if (j->isRestoring())
01394             return ;
01395     }
01396 
01397     // Send end restore message.
01398     std::auto_ptr<NetworkMessage> msg(NM_Factory::create(restoreStatus ? NetworkMessage::FEDERATION_RESTORED : NetworkMessage::FEDERATION_NOT_RESTORED)) ;
01399 
01400     msg->federate = the_federate ;
01401     msg->federation = handle ;
01402 
01403     broadcastAnyMessage(msg.get(), 0);
01404 
01405     // Reinitialize state.
01406     restoreStatus = true ;
01407     restoreInProgress = false ;
01408     G.Out(pdGendoc,"exit  Federation::federateRestoreStatus");
01409 }
01410 
01411 // ----------------------------------------------------------------------------
01413 Federate &
01414 Federation::getFederate(FederateHandle federate_handle)
01415     throw (FederateNotExecutionMember)
01416 {
01417     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
01418         if (i->getHandle() == federate_handle)
01419             return *i ;
01420     }
01421 
01422     throw FederateNotExecutionMember("Federate Handle not found.");
01423 }
01424 
01425 // ----------------------------------------------------------------------------
01427 Federate &
01428 Federation::getFederate(const char *federate_name)
01429     throw (FederateNotExecutionMember)
01430 {
01431     std::stringstream msg;
01432 
01433     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
01434         if (strcmp(i->getName(), federate_name) == 0)
01435             return *i ;
01436     }
01437 
01438     msg << "Federate <"<<federate_name<<"> not [yet] member of Federation <" << getName() <<">.";
01439     throw FederateNotExecutionMember(msg.str().c_str());
01440 }
01441 
01442 // ----------------------------------------------------------------------------
01444 
01447 bool
01448 Federation::empty() const
01449     throw (FederatesCurrentlyJoined)
01450 {
01451     if (federates.empty())
01452         return true ;
01453     else
01454         throw FederatesCurrentlyJoined("");
01455 }
01456 
01457 // ----------------------------------------------------------------------------
01459 
01462 bool
01463 Federation::check(FederateHandle federate_handle) const
01464     throw (FederateNotExecutionMember)
01465 {
01466     for (FederateList::const_iterator i = federates.begin(); i != federates.end(); ++i) {
01467         if (i->getHandle() == federate_handle)
01468             return true ;
01469     }
01470 
01471     throw FederateNotExecutionMember("");
01472 }
01473 
01474 // ----------------------------------------------------------------------------
01480 void
01481 Federation::kill(FederateHandle federate)
01482     throw ()
01483 {
01484     // NOTE: Connection to the federate is already closed.
01485     D.Out(pdInit, "Killing Federate %d.", federate);
01486 
01487     // is regulator ?
01488     try {
01489         removeRegulator(federate);
01490         D.Out(pdInit, "Regulator Federate %d removed...", federate);
01491     } catch (Exception &e) {}
01492 
01493     // is constrained ?
01494     try {
01495         removeConstrained(federate);
01496         D.Out(pdInit, "Constrained Federate %d removed...", federate);
01497     } catch (Exception &e) {}
01498 
01499     // Remove references to this federate in root object
01500     root->killFederate(federate);
01501     D[pdTrace] << "Federate " << federate << " removed from the Root Object "
01502                << endl ;
01503 
01504     // delete from federations list
01505     try {
01506         remove(federate);
01507         D.Out(pdInit, "Federate %d removed...", federate);
01508     } catch (Exception &e) {}
01509 }
01510 
01511 // ----------------------------------------------------------------------------
01512 // publishInteraction
01513 
01514 void
01515 Federation::publishInteraction(FederateHandle federate,
01516                                InteractionClassHandle interaction,
01517                                bool pub)
01518     throw (InteractionClassNotDefined,
01519            FederateNotExecutionMember,
01520            SaveInProgress,
01521            SecurityError,
01522            RestoreInProgress,
01523            RTIinternalError)
01524 {
01525     // It may throw FederateNotExecutionMember.
01526     this->check(federate);
01527 
01528     // It may throw InteractionClassNotDefined
01529     root->Interactions->publish(federate, interaction, pub);
01530     D.Out(pdRequest,
01531           "Federation %d: Federate %d has(un)published Interaction %d.",
01532           handle, federate, interaction);
01533 }
01534 
01535 // ----------------------------------------------------------------------------
01536 // publishObject
01537 
01538 void
01539 Federation::publishObject(FederateHandle federate,
01540                           ObjectClassHandle object,
01541                           std::vector <AttributeHandle> &attributes,
01542                           UShort list_size,
01543                           bool pub)
01544     throw (ObjectClassNotDefined,
01545            AttributeNotDefined,
01546            FederateNotExecutionMember,
01547            SaveInProgress,
01548            SecurityError,
01549            RestoreInProgress,
01550            RTIinternalError)
01551 {
01552     G.Out(pdGendoc,"enter Federation::publishObject");
01553     // It may throw FederateNotExecutionMember.
01554     this->check(federate);
01555 
01556     // It may throw *NotDefined
01557     root->ObjectClasses->publish(federate, object, attributes, list_size, pub);
01558 
01559     D.Out(pdRegister,
01560           "Federation %d: Federate %d(un)publishes %d attrib. of ObjClass %d.",
01561           handle, federate, list_size, object);
01562     G.Out(pdGendoc,"exit  Federation::publishObject");
01563 }
01564 
01565 // ----------------------------------------------------------------------------
01567 ObjectHandle
01568 Federation::registerObject(FederateHandle federate,
01569                            ObjectClassHandle class_handle,
01570                            const char *object_name)
01571     throw (FederateNotExecutionMember,
01572            FederateNotPublishing,
01573            ObjectAlreadyRegistered,
01574            ObjectClassNotDefined,
01575            ObjectClassNotPublished,
01576            SaveInProgress,
01577            RestoreInProgress,
01578            RTIinternalError)
01579 {
01580 
01581     ObjectHandle new_id = objectHandles.provide();
01582 
01583     G.Out(pdGendoc,"enter Federation::registerObject");
01584     D.Out(pdRegister,
01585           "Federation %d: Federate %d registering Object %d of Class %d.",
01586           handle, federate, new_id, class_handle);
01587 
01588     // create a name if necessary
01589     string strname = "" ;
01590     strname += object_name ? string(object_name) : "HLA" + new_id ;
01591 
01592     // Register Object.
01593     root->registerObjectInstance(federate, class_handle, new_id,
01594                  strname.c_str());
01595     G.Out(pdGendoc,"exit Federation::registerObject");
01596     return new_id ;
01597 }
01598 
01599 // ----------------------------------------------------------------------------
01605 void
01606 Federation::remove(FederateHandle federate_handle)
01607     throw (FederateOwnsAttributes, FederateNotExecutionMember)
01608 {
01609     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
01610         if (i->getHandle() == federate_handle) {
01611             // BUG: RemoveFederate: Should see if Federate owns attributes
01612         federateHandles.free(federate_handle);
01613             federates.erase(i);
01614 
01615             D.Out(pdInit, "Federation %d: Removed Federate %d.", handle,
01616                   federate_handle);
01617             return ;
01618         }
01619     }
01620 
01621     D.Out(pdExcept, "Federation %d could not remove unknown federate %d.",
01622           handle, federate_handle);
01623     throw FederateNotExecutionMember("");
01624 }
01625 
01626 // ----------------------------------------------------------------------------
01628 void
01629 Federation::removeConstrained(FederateHandle federate_handle)
01630     throw (FederateNotExecutionMember,
01631            SaveInProgress,
01632            RestoreInProgress,
01633            RTIinternalError)
01634 {
01635     // It may throw FederateNotExecutionMember
01636     Federate &federate = getFederate(federate_handle);
01637 
01638     if (!federate.isConstrained()) {
01639         D.Out(pdExcept, "Federate %d was not constrained.", federate_handle);
01640         throw RTIinternalError("Time constrained not enabled.");
01641     }
01642 
01643     federate.setConstrained(false);
01644     D.Out(pdTerm, "Federation %d: Federate %d is not constrained anymore.",
01645           handle, federate_handle);
01646 }
01647 
01648 // ----------------------------------------------------------------------------
01650 void
01651 Federation::removeRegulator(FederateHandle federate_handle)
01652     throw (FederateNotExecutionMember,
01653            SaveInProgress,
01654            RestoreInProgress,
01655            RTIinternalError)
01656 {
01657     // It may throw FederateNotExecutionMember
01658     Federate &federate = getFederate(federate_handle);
01659 
01660     // It may throw RTIinternalError if Federate was not regulators.
01661     regulators.remove(federate_handle);
01662 
01663     federate.setRegulator(false);
01664 
01665     D.Out(pdTerm, "Federation %d: Federate %d is not a regulator anymore.",
01666           handle, federate_handle);
01667 
01668     NM_Set_Time_Regulating msg ;
01669     msg.federation = handle ;
01670     msg.federate = federate_handle ;
01671     msg.regulatorOff();
01672 
01673     broadcastAnyMessage(&msg, 0);
01674 }
01675 
01676 // ----------------------------------------------------------------------------
01678 void
01679 Federation::unregisterSynchronization(FederateHandle federate_handle,
01680                                       const char *label)
01681     throw (FederateNotExecutionMember,
01682            FederationNotPaused,
01683            SaveInProgress,
01684            RestoreInProgress,
01685            RTIinternalError)
01686 {
01687 
01688     G.Out(pdGendoc,"enter Federation::unregisterSynchronization");
01689 
01690     this->check(federate_handle); // It may throw FederateNotExecutionMember.
01691 
01692     if (label == NULL)
01693         throw RTIinternalError("Bad pause label(null).");
01694 
01695     // Set federate synchronized on this label.
01696     Federate &federate = getFederate(federate_handle);
01697     federate.removeSynchronizationLabel(label);
01698 
01699     // Test in every federate is synchronized. Otherwise, quit method.
01700     for (FederateList::iterator j = federates.begin(); j != federates.end(); ++j) {
01701         if (j->isSynchronizationLabel(label))
01702             return ;
01703     }
01704 
01705     // All federates from federation has called synchronizationPointAchieved.
01706 
01707     D.Out(pdTerm, "Federation %d is not Paused anymore.", handle);
01708     // Remove label from federation list.
01709     std::map<const char *, const char *>::iterator i ;
01710     i = synchronizationLabels.begin();
01711     for (; i != synchronizationLabels.end(); i++) {
01712         if (!strcmp((*i).first, label)) {
01713             // Allocated by strdup().
01714             free(const_cast<char *>((*i).first));
01715             free(const_cast<char *>((*i).second));
01716             synchronizationLabels.erase(i);
01717             break ;
01718         }
01719     }
01720 
01721     // send a federationSynchronized().
01722     NM_Federation_Synchronized msg ;
01723     msg.federation = handle ;
01724     msg.federate = federate_handle ;
01725     msg.setLabel(label);
01726 
01727     broadcastAnyMessage(&msg, 0);
01728 
01729     D.Out(pdTerm, "Federation %d is synchronized on %s.", handle, label);
01730 
01731     G.Out(pdGendoc,"exit  Federation::unregisterSynchronization");
01732 
01733 }
01734 
01735 // ----------------------------------------------------------------------------
01736 // subscribeInteraction
01737 
01738 void
01739 Federation::subscribeInteraction(FederateHandle federate,
01740                                  InteractionClassHandle interaction,
01741                                  bool sub)
01742     throw (InteractionClassNotDefined,
01743            FederateNotExecutionMember,
01744            SaveInProgress,
01745            SecurityError,
01746            RestoreInProgress,
01747            RTIinternalError)
01748 {
01749     // It may throw FederateNotExecutionMember.
01750     this->check(federate);
01751 
01752     // It may throw *NotDefined
01753     root->Interactions->subscribe(federate, interaction, 0, sub);
01754     D.Out(pdRegister,
01755           "Federation %d: Federate %d(un)subscribes to Interaction %d.",
01756           handle, federate, interaction);
01757 }
01758 
01759 // ----------------------------------------------------------------------------
01760 // subscribeObject
01761 
01762 void
01763 Federation::subscribeObject(FederateHandle federate,
01764                             ObjectClassHandle object,
01765                             std::vector <AttributeHandle> &attributes,
01766                             UShort list_size)
01767     throw (ObjectClassNotDefined,
01768            AttributeNotDefined,
01769            FederateNotExecutionMember,
01770            SaveInProgress,
01771            SecurityError,
01772            RestoreInProgress,
01773            RTIinternalError)
01774 {
01775     G.Out(pdGendoc,"enter Federation::subscribeObject");
01776     // It may throw FederateNotExecutionMember.
01777     this->check(federate);
01778 
01779     // It may throw *NotDefined
01780     root->ObjectClasses->subscribe(federate, object, attributes, list_size);
01781 
01782     /*
01783      * The subscription process in CERTI:
01784      * In RTIG.cc the network messages SUBSCRIBE_OBJECT_CLASS and UNSUBSCRIBE_
01785      * OBJECT_CLASS are both mapped to the method processSubscribeObject within
01786      * RTIG_processing.cc. RTIG_proccessing invokes this method 
01787      * (subscribeObject). 
01788      * The above code line (root->ObjectClasses->subscribe(...) calls the 
01789      * subscription within the CERTI library in ObjectClassSet.cc. Further on,
01790      * ObjectClassSet::subscribe invokes ObjectClass::subscribe. That method 
01791      * first unsubscribes all attributes, afterwards the subscription is 
01792      * done in a for loop til list_size.  
01793      * This means: Unsubscription and subscription are realized by the same
01794      * method. Only the list_size parameter controls the
01795      * unsubscription/subscription process.
01796      *
01797      * Do we need a cleaner solution, e.g. separate methods for subscription/
01798      * unsubscription?
01799      */
01800 
01801     if (list_size!=0) {  // do only for subscription
01802         // get object class from object class handle    
01803         ObjectClass *objectClass = root->ObjectClasses->getObjectFromHandle(object);
01804 
01805         // get attributes of object class
01806         ObjectClass::AttributeList_t attrForObjClass = objectClass->getAttributeList();
01807 
01808         ObjectClassAttribute::PublishersList_t publishers;
01809         publishers.clear();
01810 
01811         // get publishers of attributes 
01812         // first for: iterate through the attribute list and get publishers of 
01813         //            each attribtue
01814         // second for: iterate through the temporal publishers list and store 
01815         //             non-duplicate entries in publishers
01816         ObjectClassAttribute::PublishersList_t tmp_publishers;
01817         tmp_publishers.clear();
01818         for (ObjectClass::AttributeList_t::const_iterator 
01819             i=attrForObjClass.begin();
01820         i!=attrForObjClass.end(); 
01821         i++) {
01822             tmp_publishers = (*i)->getPublishers();
01823             for (ObjectClassAttribute::PublishersList_t::const_iterator
01824                 j=tmp_publishers.begin(); 
01825             j!=tmp_publishers.end(); 
01826             j++) {
01827                 // insert only non-duplicate entries ->
01828                 // pair<iterator, bool> set::insert(const TYPE& val);
01829                 publishers.insert(*j);
01830             }
01831         tmp_publishers.clear();
01832         }
01833 
01834         // notify all publishers
01835         std::set<FederateHandle> federate_set;
01836 
01837         for (ObjectClassAttribute::PublishersList_t::const_iterator
01838             k=publishers.begin(); 
01839         k!=publishers.end(); 
01840         k++) {
01841 
01842         if (getFederate(*k).isClassRelevanceAdvisorySwitch()) {
01843             federate_set.insert(*k);
01844         }
01845         }
01846 
01847         // broadcastSomeMessage needs a vector, no set -> conversion
01848         vector<FederateHandle> federate_vector(federate_set.begin(),federate_set.end()); 
01849     
01850         NM_Start_Registration_For_Object_Class msg ;
01851         msg.federate = federate ;
01852         msg.federation = handle ;
01853         msg.setObjectClass(object);
01854 
01855         this->broadcastSomeMessage(&msg, 0, federate_vector, (unsigned short)federate_vector.size());
01856 
01857         publishers.clear();
01858         federate_set.clear();
01859         federate_vector.clear();    
01860     } 
01861     else {  // unsubscribe branch
01862     /* test if objectclass is subscribed by anyone else
01863          * -> yes : do nothing
01864          * -> no : test if publisher sets its CRA switch
01865          *      -> no : do nothing
01866          *      -> yes : inform publisher with federate service stopRegistrationForObjectClass
01867          */
01868 
01869     }
01870 
01871     D.Out(pdRegister,
01872           "Federation %d: Federate %d(un)sub. to %d attrib. of ObjClass %d.",
01873           handle, federate, list_size, object);
01874     G.Out(pdGendoc,"exit  Federation::subscribeObject");
01875 }
01876 
01877 // ----------------------------------------------------------------------------
01878 // updateAttributeValues with time
01879 
01880 void
01881 Federation::updateAttributeValues(FederateHandle federate,
01882                                   ObjectHandle id,
01883                                   std::vector <AttributeHandle> &attributes,
01884                                   std::vector <AttributeValue_t> &values,
01885                                   UShort list_size,
01886                                   FederationTime time,
01887                                   const char *tag)
01888     throw (FederateNotExecutionMember,
01889            ObjectNotKnown,
01890            AttributeNotDefined,
01891            AttributeNotOwned,
01892            SaveInProgress,
01893            RestoreInProgress,
01894            RTIinternalError)
01895 {
01896     G.Out(pdGendoc,"enter Federation::updateAttributeValues with time");
01897     // It may throw FederateNotExecutionMember.
01898     this->check(federate);
01899 
01900     // It may throw *NotDefined
01901     root->ObjectClasses->updateAttributeValues(federate, id, attributes, values,
01902                                                list_size, time, tag);
01903 
01904     D.Out(pdRegister,
01905           "Federation %d: Federate %d updated attributes of Object %d.",
01906           handle, federate, id);
01907     G.Out(pdGendoc,"exit  Federation::updateAttributeValues with time");
01908 }
01909 
01910 // ----------------------------------------------------------------------------
01911 // updateAttributeValues without time
01912 
01913 void
01914 Federation::updateAttributeValues(FederateHandle federate,
01915                                   ObjectHandle id,
01916                                   std::vector <AttributeHandle> &attributes,
01917                                   std::vector <AttributeValue_t> &values,
01918                                   UShort list_size,
01919                                   const char *tag)
01920     throw (FederateNotExecutionMember,
01921            ObjectNotKnown,
01922            AttributeNotDefined,
01923            AttributeNotOwned,
01924            SaveInProgress,
01925            RestoreInProgress,
01926            RTIinternalError)
01927 {
01928     G.Out(pdGendoc,"enter Federation::updateAttributeValues without time");
01929     // It may throw FederateNotExecutionMember.
01930     this->check(federate);
01931 
01932     // It may throw *NotDefined
01933     root->ObjectClasses->updateAttributeValues(federate, id, attributes, values,
01934                                                list_size, tag);
01935 
01936     D.Out(pdRegister,
01937           "Federation %d: Federate %d updated attributes of Object %d.",
01938           handle, federate, id);
01939     G.Out(pdGendoc,"exit  Federation::updateAttributeValues without time");
01940 }
01941 // ----------------------------------------------------------------------------
01943 void
01944 Federation::updateRegulator(FederateHandle federate_handle,
01945                             FederationTime time)
01946     throw (FederateNotExecutionMember,
01947            RTIinternalError)
01948 {
01949     // It may throw FederateNotExecutionMember
01950     Federate &federate = getFederate(federate_handle);
01951 
01952     if (!federate.isRegulator()) {
01953         D.Out(pdExcept, "Federate %d is not a regulator.", federate_handle);
01954         throw RTIinternalError("Time regulation not enabled.");
01955     }
01956 
01957     D.Out(pdTerm, "Federation %d: Federate %d's new time is %f.",
01958           handle, federate_handle, time.getTime());
01959 
01960     regulators.update(federate_handle, time);
01961 
01962     NM_Message_Null msg ;
01963     msg.federation = handle ;
01964     msg.federate = federate_handle ;
01965     msg.setDate(time);
01966 
01967     broadcastAnyMessage(&msg, federate_handle);
01968 }
01969 
01970 // ----------------------------------------------------------------------------
01971 // isOwner (isAttributeOwnedByFederate)
01972 bool
01973 Federation::isOwner(FederateHandle federate,
01974                     ObjectHandle id,
01975                     AttributeHandle attribute)
01976     throw (FederateNotExecutionMember,
01977            ObjectNotKnown,
01978            AttributeNotDefined,
01979            SaveInProgress,
01980            RestoreInProgress,
01981            RTIinternalError)
01982 {
01983     // It may throw FederateNotExecutionMember.
01984     this->check(federate);
01985 
01986     D.Out(pdDebug, "Owner of Object %u Atrribute %u", id, attribute);
01987 
01988     // It may throw *NotDefined
01989     return root->objects->isAttributeOwnedByFederate(id, attribute, federate);
01990 }
01991 
01992 // ----------------------------------------------------------------------------
01993 // queryAttributeOwnership
01994 
01995 void
01996 Federation::queryAttributeOwnership(FederateHandle federate,
01997                                     ObjectHandle id,
01998                                     AttributeHandle attribute)
01999     throw (FederateNotExecutionMember,
02000            ObjectNotKnown,
02001            AttributeNotDefined,
02002            SaveInProgress,
02003            RestoreInProgress,
02004            RTIinternalError)
02005 {
02006     // It may throw FederateNotExecutionMember.
02007     this->check(federate);
02008 
02009     D.Out(pdDebug, "Owner of Object %u Atrribute %u", id, attribute);
02010 
02011     // It may throw *NotDefined
02012     root->objects->queryAttributeOwnership(id, attribute, federate);
02013 }
02014 
02015 // ----------------------------------------------------------------------------
02016 // negotiateDivestiture (negotiatedAttributeOwnershipDivestiture)
02017 
02018 void
02019 Federation::negotiateDivestiture(FederateHandle federate,
02020                                  ObjectHandle id,
02021                                  std::vector <AttributeHandle> &attribs,
02022                                  UShort list_size,
02023                                  const char *tag)
02024     throw (FederateNotExecutionMember,
02025            ObjectNotKnown,
02026            AttributeNotDefined,
02027            AttributeNotOwned,
02028            AttributeAlreadyBeingDivested,
02029            SaveInProgress,
02030            RestoreInProgress,
02031            RTIinternalError)
02032 {
02033     // It may throw FederateNotExecutionMember.
02034     this->check(federate);
02035 
02036     // It may throw *NotDefined
02037     root->ObjectClasses->negotiatedAttributeOwnershipDivestiture(federate,
02038                                                                  id,
02039                                                                  attribs,
02040                                                                  list_size,
02041                                                                  tag);
02042 }
02043 
02044 // ----------------------------------------------------------------------------
02045 // acquireIfAvailable (attributeOwnershipAcquisitionIfAvailable)
02046 
02047 void
02048 Federation::acquireIfAvailable(FederateHandle federate,
02049                                ObjectHandle id,
02050                                std::vector <AttributeHandle> &attribs,
02051                                UShort list_size)
02052     throw (ObjectNotKnown,
02053            ObjectClassNotPublished,
02054            AttributeNotDefined,
02055            AttributeNotPublished,
02056            FederateOwnsAttributes,
02057            AttributeAlreadyBeingAcquired,
02058            FederateNotExecutionMember,
02059            SaveInProgress,
02060            RestoreInProgress,
02061            RTIinternalError)
02062 {
02063     // It may throw FederateNotExecutionMember.
02064     this->check(federate);
02065 
02066     // It may throw *NotDefined
02067     root->ObjectClasses->attributeOwnershipAcquisitionIfAvailable(federate,
02068                                                                   id,
02069                                                                   attribs,
02070                                                                   list_size);
02071 }
02072 
02073 // ----------------------------------------------------------------------------
02074 // divest (unconditionalAttributeOwnershipDivestiture)
02075 
02076 void
02077 Federation::divest(FederateHandle federate,
02078                    ObjectHandle id,
02079                    std::vector <AttributeHandle> &attrs,
02080                    UShort list_size)
02081     throw (ObjectNotKnown,
02082            AttributeNotDefined,
02083            AttributeNotOwned,
02084            FederateNotExecutionMember,
02085            SaveInProgress,
02086            RestoreInProgress,
02087            RTIinternalError)
02088 {
02089     // It may throw FederateNotExecutionMember.
02090     this->check(federate);
02091 
02092     // It may throw *NotDefined
02093     root->ObjectClasses->unconditionalAttributeOwnershipDivestiture(federate,
02094                                                                     id,
02095                                                                     attrs,
02096                                                                     list_size);
02097 }
02098 
02099 // ----------------------------------------------------------------------------
02100 // attributeOwnershipAcquisition
02101 
02102 void
02103 Federation::acquire(FederateHandle federate,
02104                     ObjectHandle id,
02105                     std::vector <AttributeHandle> &attributes,
02106                     UShort list_size,
02107                     const char *tag)
02108     throw (ObjectNotKnown,
02109            ObjectClassNotPublished,
02110            AttributeNotDefined,
02111            AttributeNotPublished,
02112            FederateOwnsAttributes,
02113            FederateNotExecutionMember,
02114            SaveInProgress,
02115            RestoreInProgress,
02116            RTIinternalError)
02117 {
02118     // It may throw FederateNotExecutionMember.
02119     this->check(federate);
02120 
02121     // It may throw *NotDefined
02122     root->ObjectClasses->attributeOwnershipAcquisition(federate,
02123                                                        id,
02124                                                        attributes,
02125                                                        list_size,
02126                                                        tag);
02127 
02128     D.Out(pdDebug, "Acquisition on Object %u ", id);
02129 }
02130 
02131 // ----------------------------------------------------------------------------
02132 // cancelDivestiture (cancelNegotiatedAttributeOwnershipDivestiture)
02133 
02134 void
02135 Federation::cancelDivestiture(FederateHandle federate,
02136                               ObjectHandle id,
02137                               std::vector <AttributeHandle> &attributes,
02138                               UShort list_size)
02139     throw (ObjectNotKnown,
02140            AttributeNotDefined,
02141            AttributeNotOwned,
02142            AttributeDivestitureWasNotRequested,
02143            FederateNotExecutionMember,
02144            SaveInProgress,
02145            RestoreInProgress,
02146            RTIinternalError)
02147 {
02148     // It may throw FederateNotExecutionMember.
02149     this->check(federate);
02150 
02151     // It may throw *NotDefined
02152     root->objects->cancelNegotiatedAttributeOwnershipDivestiture(federate,
02153                                                                  id,
02154                                                                  attributes,
02155                                                                  list_size);
02156 
02157     D.Out(pdDebug, "CancelDivestiture sur Objet %u ", id);
02158 }
02159 
02160 // ----------------------------------------------------------------------------
02161 // respondRelease (attributeOwnershipRealeaseResponse)
02162 
02163 AttributeHandleSet*
02164 Federation::respondRelease(FederateHandle federate,
02165                            ObjectHandle id,
02166                            std::vector <AttributeHandle> &attributes,
02167                            UShort list_size)
02168     throw (ObjectNotKnown,
02169            AttributeNotDefined,
02170            AttributeNotOwned,
02171            FederateWasNotAskedToReleaseAttribute,
02172            FederateNotExecutionMember,
02173            SaveInProgress,
02174            RestoreInProgress,
02175            RTIinternalError)
02176 {
02177     // It may throw FederateNotExecutionMember.
02178     this->check(federate);
02179 
02180     D.Out(pdDebug, "RespondRelease on Object %u.", id);
02181 
02182     // It may throw *NotDefined
02183     return(root->ObjectClasses->attributeOwnershipReleaseResponse(federate,
02184                                                                   id,
02185                                                                   attributes,
02186                                                                   list_size));
02187 }
02188 
02189 // ----------------------------------------------------------------------------
02190 // cancelAttributeOwnershipAcquisition
02191 
02192 void
02193 Federation::cancelAcquisition(FederateHandle federate,
02194                               ObjectHandle id,
02195                               std::vector <AttributeHandle> &attributes,
02196                               UShort list_size)
02197     throw (ObjectNotKnown,
02198            AttributeNotDefined,
02199            AttributeAlreadyOwned,
02200            AttributeAcquisitionWasNotRequested,
02201            FederateNotExecutionMember,
02202            SaveInProgress,
02203            RestoreInProgress,
02204            RTIinternalError)
02205 {
02206     // It may throw FederateNotExecutionMember.
02207     this->check(federate);
02208 
02209     D.Out(pdDebug, "CancelAcquisition sur Objet %u ", id);
02210 
02211     // It may throw *NotDefined
02212     root->ObjectClasses->cancelAttributeOwnershipAcquisition(federate,
02213                                                              id,
02214                                                              attributes,
02215                                                              list_size);
02216 }
02217 
02218 // ----------------------------------------------------------------------------
02219 long
02220 Federation::createRegion(FederateHandle federate,
02221                          SpaceHandle space,
02222                          long nb_extents)
02223     throw (SpaceNotDefined, InvalidExtents, SaveInProgress, RestoreInProgress,
02224            RTIinternalError)
02225 {
02226     this->check(federate);
02227 
02228     return root->createRegion(space, nb_extents);
02229 }
02230 
02231 // ----------------------------------------------------------------------------
02232 // modifyRegion
02233 void
02234 Federation::modifyRegion(FederateHandle federate, RegionHandle region,
02235              const std::vector<Extent> &extents)
02236     throw (RegionNotKnown, InvalidExtents, SaveInProgress, RestoreInProgress,
02237        RTIinternalError)
02238 {
02239     check(federate);
02240     root->modifyRegion(region, extents);
02241 }
02242 
02243 // ----------------------------------------------------------------------------
02245 void
02246 Federation::deleteRegion(FederateHandle federate,
02247                          long region)
02248     throw (RegionNotKnown, RegionInUse, SaveInProgress, RestoreInProgress,
02249            RTIinternalError)
02250 {
02251     this->check(federate);
02252 
02253     if (saveInProgress) {
02254         throw SaveInProgress("");
02255     }
02256     if (restoreInProgress) {
02257         throw RestoreInProgress("");
02258     }
02259 
02260     // TODO: check RegionInUse
02261     root->deleteRegion(region);
02262 }
02263 
02264 // ----------------------------------------------------------------------------
02266 void
02267 Federation::associateRegion(FederateHandle federate,
02268                 ObjectHandle object,
02269                 RegionHandle the_handle,
02270                 unsigned short nb,
02271                 std::vector <AttributeHandle> &attributes)
02272     throw (RegionNotKnown, SaveInProgress, RestoreInProgress, RTIinternalError)
02273 {
02274     check(federate);
02275 
02276     RTIRegion *region = root->getRegion(the_handle);
02277 
02278     root->getObject(object)->unassociate(region);
02279 
02280     for (int i = 0 ; i < nb ; ++i) {
02281     root->getObjectAttribute(object, attributes[i])->associate(region);
02282     }
02283 }
02284 
02285 // ----------------------------------------------------------------------------
02287 void
02288 Federation::unassociateRegion(FederateHandle federate, ObjectHandle object,
02289                   RegionHandle the_handle)
02290     throw (RegionNotKnown, SaveInProgress, RestoreInProgress,
02291        RTIinternalError)
02292 {
02293     check(federate);
02294 
02295     RTIRegion *region = root->getRegion(the_handle);
02296     root->getObject(object)->unassociate(region);
02297 }
02298 
02299 // ----------------------------------------------------------------------------
02301 void
02302 Federation::subscribeAttributesWR(FederateHandle federate,
02303                   ObjectClassHandle c,
02304                   RegionHandle region_handle,
02305                   unsigned short nb,
02306                   std::vector <AttributeHandle> &attributes)
02307     throw (RegionNotKnown,
02308        SaveInProgress,
02309        RestoreInProgress,
02310        RTIinternalError)
02311 {
02312     check(federate);
02313     root->ObjectClasses->subscribe(federate, c, attributes, nb,
02314                    root->getRegion(region_handle));
02315 }
02316 
02317 // ----------------------------------------------------------------------------
02319 void
02320 Federation::unsubscribeAttributesWR(FederateHandle federate,
02321                     ObjectClassHandle object_class,
02322                     RegionHandle region_handle)
02323     throw (RegionNotKnown,
02324            SaveInProgress,
02325            RestoreInProgress,
02326            RTIinternalError)
02327 {
02328     check(federate);
02329 
02330     RTIRegion *region = root->getRegion(region_handle);
02331 
02332     root->getObjectClass(object_class)->unsubscribe(federate, region);
02333 }
02334 
02335 // ----------------------------------------------------------------------------
02336 void
02337 Federation::subscribeInteractionWR(FederateHandle federate,
02338                    InteractionClassHandle interaction,
02339                    RegionHandle region_handle)
02340     throw (RegionNotKnown,
02341            SaveInProgress,
02342            RestoreInProgress,
02343            RTIinternalError)
02344 {
02345     check(federate);
02346 
02347     RTIRegion *region = root->getRegion(region_handle);
02348 
02349     root->getInteractionClass(interaction)->subscribe(federate, region);
02350 }
02351 
02352 // ----------------------------------------------------------------------------
02353 void
02354 Federation::unsubscribeInteractionWR(FederateHandle federate,
02355                      InteractionClassHandle interaction,
02356                      RegionHandle region_handle)
02357     throw (RegionNotKnown,
02358            SaveInProgress,
02359            RestoreInProgress,
02360            RTIinternalError)
02361 {
02362     check(federate);
02363 
02364     RTIRegion *region = root->getRegion(region_handle);
02365 
02366     root->getInteractionClass(interaction)->unsubscribe(federate, region);
02367 }
02368 
02369 // ----------------------------------------------------------------------------
02370 ObjectHandle
02371 Federation::registerObjectWithRegion(FederateHandle federate,
02372                      ObjectClassHandle class_handle,
02373                      const char *object_name,
02374                      RegionHandle region_handle,
02375                      int nb,
02376                      std::vector <AttributeHandle> &attributes)
02377     throw (ObjectClassNotDefined, ObjectClassNotPublished,
02378        AttributeNotDefined, AttributeNotPublished, RegionNotKnown,
02379        InvalidRegionContext, ObjectAlreadyRegistered,
02380        SaveInProgress, RestoreInProgress,
02381        RTIinternalError)
02382 {
02383     G.Out(pdGendoc,"enter Federation::registerObjectWithRegion");
02384     check(federate);
02385 
02386     // Register object
02387     ObjectHandle object = objectHandles.provide();
02388     D[pdDebug] << "Register object with region : Object " << object
02389            << ", class " << class_handle << ", region " << region_handle
02390            << std::endl ;
02391     string strname = "" ;    // create a name if necessary
02392     strname += object_name ? string(object_name) : "HLA" + object ;
02393 
02394     root->registerObjectInstance(federate, class_handle, object,
02395                  strname.c_str());
02396 
02397     D[pdDebug] << "- object \"" << strname.c_str()
02398            << "\" registered" << std::endl ;
02399 
02400     // Associate region
02401     RTIRegion *region = root->getRegion(region_handle);
02402     root->getObject(object)->unassociate(region);
02403 
02404     for (int i = 0 ; i < nb ; ++i) {
02405     root->getObjectAttribute(object, attributes[i])->associate(region);
02406     }
02407 
02408     D[pdDebug] << "- " << nb << " attribute(s) associated with region "
02409            << region_handle << std::endl ;
02410     G.Out(pdGendoc,"exit  Federation::registerObjectWithRegion");
02411     return object ;
02412 }
02413 
02414 // ----------------------------------------------------------------------------
02415 bool
02416 Federation::restoreXmlData()
02417 {
02418 #ifndef HAVE_XML
02419     return false ;
02420 #else
02421     xmlNodePtr cur ;
02422 
02423     cur = xmlDocGetRootElement(doc);
02424     if (cur == 0) {
02425         cerr << "XML file is empty" << endl ;
02426         xmlFreeDoc(doc);
02427         return false ;
02428     }
02429 
02430     // Is this root element an ROOT_NODE ?
02431     if (xmlStrcmp(cur->name, ROOT_NODE)) {
02432         cerr << "Wrong XML file: not the expected root node" << endl ;
02433         return false ;
02434     }
02435 
02436     cur = cur->xmlChildrenNode ;
02437     if (xmlStrcmp(cur->name, NODE_FEDERATION)) {
02438         cerr << "Wrong XML file structure" << endl ;
02439         return false ;
02440     }
02441 
02442     if (strcmp(name.c_str(), XmlParser::CleanXmlGetProp(cur,(const xmlChar*)"name")) != 0) {
02443         cerr << "Wrong federation name" << endl ;
02444     }
02445 
02446 
02447     cur = cur->xmlChildrenNode ;
02448 
02449     bool status ;
02450     while (cur != NULL) {
02451         if ((!xmlStrcmp(cur->name, NODE_FEDERATE))) {
02452             for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
02453                 if (!strcmp(i->getName(),XmlParser::CleanXmlGetProp(cur, (const xmlChar*) "name"))) {
02454                     // Set federate constrained status
02455                     if (!strcmp("true", XmlParser::CleanXmlGetProp(cur, (const xmlChar*) "constrained"))) {
02456                         status = true ;
02457                     }
02458                     else {
02459                         status = false ;
02460                     }
02461 
02462                     i->setConstrained(status);
02463 
02464                     // Set federate regulating status
02465                     status = !strcmp("true", XmlParser::CleanXmlGetProp(cur, (const xmlChar *) "regulator"));
02466 
02467                     i->setRegulator(status);
02468 
02469                     i->setHandle(strtol(XmlParser::CleanXmlGetProp(cur, (const xmlChar *) "handle"), 0, 10));
02470                     break ;
02471                 }
02472             }
02473         }
02474         cur = cur->next ;
02475     }
02476 
02477     return status ;
02478 #endif // HAVE_XML
02479 }
02480 
02481 // ----------------------------------------------------------------------------
02482 bool
02483 Federation::saveXmlData()
02484 {
02485 #ifndef HAVE_XML
02486     return false ;
02487 #else
02488     doc = xmlNewDoc((const xmlChar *) "1.0");
02489     doc->children = xmlNewDocNode(doc, NULL, ROOT_NODE, NULL);
02490 
02491     xmlNodePtr federation ;
02492     federation = xmlNewChild(doc->children, NULL, NODE_FEDERATION, NULL);
02493 
02494     xmlSetProp(federation, (const xmlChar *) "name", (const xmlChar *) name.c_str());
02495 
02496     char t[10] ;
02497     sprintf(t, "%ld", handle);
02498     xmlSetProp(federation, (const xmlChar *) "handle", (const xmlChar *) t);
02499 
02500     xmlNodePtr federate ;
02501 
02502     for (FederateList::iterator i = federates.begin(); i != federates.end(); ++i) {
02503         federate = xmlNewChild(federation, NULL, NODE_FEDERATE, NULL);
02504 
02505         xmlSetProp(federate,
02506                    (const xmlChar *) "name",
02507                    (const xmlChar *) i->getName());
02508 
02509         sprintf(t, "%ld", i->getHandle());
02510         xmlSetProp(federate, (const xmlChar *) "handle", (const xmlChar *) t);
02511 
02512         xmlSetProp(federate,
02513                    (const xmlChar *)"constrained", (const xmlChar *)
02514                    ((i->isConstrained()) ? "true" : "false"));
02515         xmlSetProp(federate, (const xmlChar *) "regulator",
02516                    (const xmlChar *)((i->isRegulator()) ? "true" : "false"));
02517     }
02518 
02519     xmlSetDocCompressMode(doc, 9);
02520 
02521     string filename = string(name) + "_" + string(saveLabel) + ".xcs" ;
02522     xmlSaveFile(filename.c_str(), doc);
02523 
02524     // TODO: tests
02525 
02526     return true ;
02527 #endif // HAVE_XML
02528 }
02529 // ----------------------------------------------------------------------------
02530 FederateHandle
02531 Federation::requestObjectOwner(FederateHandle theFederateHandle,
02532                              ObjectHandle theObject,
02533                              std::vector <AttributeHandle> &theAttributeList,
02534                              UShort theListSize)
02535         throw (ObjectNotKnown)
02536 {
02537 FederateHandle theOwnerHandle ;
02538 NM_Provide_Attribute_Value_Update mess ;
02539 
02540     G.Out(pdGendoc,"enter Federation::requestObjectOwner");
02541 
02542     // Request Object.
02543     theOwnerHandle = root->requestObjectOwner(theFederateHandle,theObject) ;
02544 
02545     // Send a PROVIDE_ATTRIBUTE_VALUE_UPDATE to the owner
02546     mess.federate = theFederateHandle ;
02547     mess.object = theObject ;
02548     mess.handleArraySize = theListSize ;
02549     mess.handleArray.resize(theListSize) ;
02550     for (int i = 0 ; i < theListSize ; i++)
02551         {
02552         mess.handleArray[i] = theAttributeList[i] ;
02553         }
02554 
02555      // JYR : BUG if getSocketLink return NULL means
02556      // owner federate has been killed and so rtig don't crash
02557      // better development needed
02558      if ( server->getSocketLink(theOwnerHandle) == NULL )
02559         {
02560         throw ObjectNotKnown ( "Owner federate killed") ;
02561         }
02562 
02563      mess.send(server->getSocketLink(theOwnerHandle),NM_msgBufSend);
02564 
02565    G.Out(pdGendoc,"            requestObjectOwner ===> write PAVU to RTIA %d"
02566                    ,theOwnerHandle);
02567     G.Out(pdGendoc,"exit  Federation::requestObjectOwner");
02568     return(theOwnerHandle);
02569 
02570 }
02571 
02572 }} // namespace certi/rtig
02573 
02574 // $Id: Federation.cc,v 3.105 2009/04/08 10:47:18 approx Exp $
02575 

Generated on Thu Apr 30 15:53:48 2009 for CERTIDeveloperDocumentation by doxygen 1.5.5