# 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