📄 rtiambassador.cc
字号:
// -*- mode:C++ ; tab-width:4 ; c-basic-offset:4 ; indent-tabs-mode:nil -*-// ----------------------------------------------------------------------------// CERTI - HLA RunTime Infrastructure// Copyright (C) 2002, 2003 ONERA//// This file is part of CERTI-libRTI//// CERTI-libRTI is free software ; you can redistribute it and/or// modify it under the terms of the GNU Lesser General Public License// as published by the Free Software Foundation ; either version 2 of// the License, or (at your option) any later version.//// CERTI-libRTI is distributed in the hope that it will be useful, but// WITHOUT ANY WARRANTY ; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU// Lesser General Public License for more details.//// You should have received a copy of the GNU Lesser General Public// License along with this program ; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307// USA//// $Id: RTIambassador.cc,v 3.18 2003/03/21 15:06:46 breholee Exp $// ----------------------------------------------------------------------------#include <config.h>#include "baseTypes.hh"#include "RTItypes.hh"#include "GAV.hh"#include "FederateAmbassador.hh"#include "Message.hh"#include "SocketUN.hh"#include "RootObject.hh"#include "fedtime.hh"#include "PrettyDebug.hh"#include "RTIambassador.hh"namespace certi {static pdCDebug D("LIBRTI", "(libRTI) - ");// ----------------------------------------------------------------------------voidRTIambassador::leave(const char *msg){ cout << "libRTI: " << msg << endl ; exit(EXIT_FAILURE);}// ----------------------------------------------------------------------------voidRTIambassador::executeService(Message *req, Message *rep){ // raise exception if reentrant call. if (is_reentrant) throw ConcurrentAccessAttempted(); D.Out(pdDebug, "sending request to RTIA."); is_reentrant = true ; try { req->write((SocketUN *) this); } catch (NetworkError) { cout << "LibRTI: Catched NetworkError (write), " << "throw RTIinternalError." << endl ; throw RTIinternalError(); } D.Out(pdDebug, "waiting RTIA reply."); // waiting RTI reply. try { rep->read((SocketUN *) this); } catch (NetworkError) { cout << "LibRTI: Catched NetworkError (read), " << "throw RTIinternalError." << endl ; throw RTIinternalError(); } D.Out(pdDebug, "RTIA reply received."); if (rep->type != req->type) { cout << "LibRTI: Assertion failed: rep->type != req->type" << endl ; throw RTIinternalError("RTIambassador::executeService: " "rep->type != req->type"); } is_reentrant = false ; D.Out(pdDebug, "processing returned exception (from reply)."); processException(rep); D.Out(pdDebug, "exception processed.");}// ----------------------------------------------------------------------------//! Start RTIambassador processes for communication with RTIG./*! When a new RTIambassador is created in the application, a new process rtia is launched. This process is used for data exchange with rtig server. This process connects to rtia after one second delay (UNIX socket).*/RTIambassador::RTIambassador(void) throw (MemoryExhausted, RTIinternalError) : SocketUN(stIgnoreSignal){ is_reentrant = false ; const char *rtiaexec = "rtia" ; const char *rtiaenv = getenv("CERTI_RTIA"); const char *rtiacall ; if (rtiaenv) rtiacall = rtiaenv ; else rtiacall = rtiaexec ; // creating RTIA process. switch((pid_RTIA = fork())) { case -1: // fork failed. perror("fork"); throw RTIinternalError("fork failed in RTIambassador constructor"); break ; case 0: // child process (RTIA). execlp(rtiacall, NULL); perror("execlp"); cerr << "Could not launch RTIA process." << endl << "Maybe RTIA is not in search PATH environment." << endl ; exit(-1); default: // father process (Federe). sleep(1); connectUN(pid_RTIA); break ; }}// ----------------------------------------------------------------------------//! Closes processes./*! When destructor is called, kill rtia process. */RTIambassador::~RTIambassador(void){ kill(pid_RTIA, SIGINT);}// ===========================================================================// Data Integrity// ===========================================================================//! Convert an object string to a network capable message./*! objectToString is used to convert data to a network message for sending. Special caracters are ?, \ and \0. - \0 : it is converted to a single ?, - ? : converted to pattern "\?[??]+\", - \ : converted to pattern "\??[??]+\". - other : keep caracter. Differenciation between ? and \ is made on parity number of ? contained between \.*/voidRTIambassador::objectToString(const char *init_string, ULong size, char *end_string){ ULong i = 0 ; ULong j = 0 ; while (i < size) { switch(init_string[i]) { case '\0': end_string[j++] = '?' ; i++ ; break ; case '?': end_string[j++] = '\\' ; end_string[j++] = '?' ; i++ ; while ((init_string[i] == '?') && (i < size)) { end_string[j++] = '?' ; end_string[j++] = '?' ; i++ ; } end_string[j++] = '\\' ; break ; case '\\': end_string[j++] = '\\' ; end_string[j++] = '?' ; end_string[j++] = '?' ; i++ ; while ((init_string[i] == '\\') && (i<size)) { end_string[j++] = '?' ; end_string[j++] = '?' ; i++ ; } end_string[j++] = '\\' ; break ; default: end_string[j++] = init_string[i] ; i++ ; } } end_string[j++] = '\0' ;}// ----------------------------------------------------------------------------//! Returns buffer size needed to store network message made by objectToStringvoidRTIambassador::getObjectToStringLength(char *init_string, ULong init_size, ULong &size){ ULong counter = 0 ; ULong i = 0 ; size = 0 ; while (i < init_size) { switch(init_string[i]) { case '?': i++ ; while ((init_string[i] == '?') && (i < init_size)) { counter++ ; i++ ; } size += 3 + 2 * counter ; counter = 0 ; break ; case '\\': i++ ; while ((init_string[i] == '\\') && (i < init_size)) { counter++ ; i++ ; } size += 4 + 2 * counter ; counter = 0 ; default: size++ ; i++ ; } } size ++ ;}// ===========================================================================// FEDERATION MANAGEMENT// ===========================================================================// ----------------------------------------------------------------------------//! Create Federation Execution./*! Send a CREATE_FEDERATION_EXECUTION request type to inform rtia process a new federation is being created.*/voidRTIambassador::createFederationExecution(const char *executionName, const char *FED) throw (FederationExecutionAlreadyExists, ConcurrentAccessAttempted, CouldNotOpenFED, //not implemented ErrorReadingFED, //not implemented SaveInProgress, RestoreInProgress, RTIinternalError){ Message req, rep ; // char *exeName = new char[20] ; // strcpy(exeName, executionName); // strcat(exeName, "\56"); // strcat(exeName, "fed"); req.type = CREATE_FEDERATION_EXECUTION ; req.setFederationName(executionName); // if (!strcasecmp(FED, exeName)) { executeService(&req, &rep); // } // else { // throw RTIinternalError(); // }}// ----------------------------------------------------------------------------//! Destroy Federation Execution.voidRTIambassador::destroyFederationExecution(const char *executionName) throw (FederatesCurrentlyJoined, FederationExecutionDoesNotExist, ConcurrentAccessAttempted, SaveInProgress, RestoreInProgress, RTIinternalError){ Message req, rep ; req.type = DESTROY_FEDERATION_EXECUTION ; req.setFederationName(executionName); executeService(&req, &rep);}// ----------------------------------------------------------------------------//! Join Federation Execution.FederateHandleRTIambassador::joinFederationExecution(const char *yourName, const char *executionName, FederateAmbassadorPtr federateAmbassadorReference) throw (FederateAlreadyExecutionMember, FederationExecutionDoesNotExist, CouldNotOpenRID, //CERTI ErrorReadingRID, //CERTI CouldNotOpenFED, //not implemented ErrorReadingFED, //not implemented ConcurrentAccessAttempted, SaveInProgress, //not implemented RestoreInProgress, //not implemented RTIinternalError){ Message req, rep ; fed_amb = (FederateAmbassador *) federateAmbassadorReference ; req.type = JOIN_FEDERATION_EXECUTION ; req.setFederateName(yourName); req.setFederationName(executionName); executeService(&req, &rep); return rep.federate ;}// ----------------------------------------------------------------------------//! Resign Federation Execution.voidRTIambassador::resignFederationExecution(ResignAction theAction) throw (FederateOwnsAttributes, FederateNotExecutionMember, InvalidResignAction, ConcurrentAccessAttempted, RTIinternalError){ Message req, rep ; // envoyer la requete au RTI req.type = RESIGN_FEDERATION_EXECUTION ; req.resignAction = theAction ; executeService(&req, &rep);}// ----------------------------------------------------------------------------//! Register Federation Synchronization PointvoidRTIambassador::registerFederationSynchronizationPoint(const char *label, const char *the_tag) throw (FederateNotExecutionMember, ConcurrentAccessAttempted, SaveInProgress, RestoreInProgress, RTIinternalError){ Message req, rep ; req.type = REGISTER_FEDERATION_SYNCHRONIZATION_POINT ; req.setLabel(label); req.setTag(the_tag); executeService(&req, &rep);}// ----------------------------------------------------------------------------void RTIambassador::registerFederationSynchronizationPoint(const char */*label*/, const char */*theTag*/, const FederateHandleSet &/*syncSet*/) throw (FederateNotExecutionMember, ConcurrentAccessAttempted, SaveInProgress, RestoreInProgress, RTIinternalError, UnimplementedService) //CERTI{ throw UnimplementedService();}// ----------------------------------------------------------------------------//! Synchronization Point AchievedvoidRTIambassador::synchronizationPointAchieved(const char *label) throw (SynchronizationPointLabelWasNotAnnounced, FederateNotExecutionMember, ConcurrentAccessAttempted, SaveInProgress, RestoreInProgress, RTIinternalError){ Message req, rep ; req.type = SYNCHRONIZATION_POINT_ACHIEVED ; req.setLabel(label); executeService(&req, &rep);}// ----------------------------------------------------------------------------//! Request Federation Save (not implemented)voidRTIambassador::requestFederationSave(const char */*label*/, const FedTime& /*theTime*/) throw (FederationTimeAlreadyPassed, InvalidFederationTime, FederateNotExecutionMember,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -