00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <config.h>
00025 #include "TimeManagement.hh"
00026 #include "NM_Classes.hh"
00027 #include <float.h>
00028
00029 namespace certi {
00030 namespace rtia {
00031
00032 namespace {
00033
00034 PrettyDebug D("RTIA_TM", __FILE__);
00035 static PrettyDebug G("GENDOC",__FILE__) ;
00036 const double epsilon2 = 1.0e-4 ;
00037
00038 }
00039
00040
00044 void
00045 TimeManagement::advance(bool &msg_restant, TypeException &e)
00046 {
00047 switch(_avancee_en_cours) {
00048 case TAR:
00049 case TARA:
00050 D.Out(pdTrace, "Call to TimeAdvance.");
00051 timeAdvance(msg_restant, e);
00052 break ;
00053 case NER:
00054 case NERA:
00055 D.Out(pdTrace, "Call to NextEventAdvance.");
00056 nextEventAdvance(msg_restant, e);
00057 break ;
00058 default:
00059 D.Out(pdTrace, "Unexpected case in advance: %d.", _avancee_en_cours);
00060
00061
00062
00063
00064
00065 }
00066 }
00067
00068
00070 TimeManagement::TimeManagement(Communications *GC,
00071 Queues *GQueues,
00072 FederationManagement *GF,
00073 DeclarationManagement *GD,
00074 ObjectManagement *GO,
00075 OwnershipManagement *GP)
00076 : LBTS()
00077 {
00078 comm = GC ;
00079 queues = GQueues ;
00080 fm = GF ;
00081 dm = GD ;
00082 om = GO ;
00083 owm = GP ;
00084
00085 lastNullMessageDate = 0.0 ;
00086
00087 _avancee_en_cours = PAS_D_AVANCEE ;
00088 _tick_state = NO_TICK;
00089 _asynchronous_delivery = false ;
00090
00091 _heure_courante = 0.0 ;
00092 _lookahead_courant = 0.0 ;
00093 _est_regulateur = false ;
00094 _est_contraint = false ;
00095 }
00096
00097
00099 void TimeManagement::sendNullMessage(FederationTime heure_logique)
00100 {
00101 NM_Message_Null msg ;
00102
00103 msg.setDate(heure_logique);
00104 heure_logique += _lookahead_courant ;
00105
00106 if (heure_logique > lastNullMessageDate) {
00107 msg.federation = fm->_numero_federation ;
00108 msg.federate = fm->federate ;
00109 msg.setDate(heure_logique) ;
00110
00111 comm->sendMessage(&msg);
00112 lastNullMessageDate = heure_logique ;
00113 D.Out(pdDebug, "NULL message sent (Time = %f).", heure_logique.getTime()) ;
00114 }
00115 else {
00116 D.Out(pdExcept, "NULL message not sent (Time = %f, Last = %f).",
00117 heure_logique.getTime(), lastNullMessageDate.getTime());
00118 }
00119 }
00120
00121
00123 bool
00124 TimeManagement::executeFederateService(NetworkMessage &msg)
00125 {
00126 G.Out(pdGendoc,"enter TimeManagement::executeFederateService for type %d",msg.getType());
00127 D.Out(pdRequest, "Execute federate service: Type %d.", msg.getType());
00128
00129 _tick_state = TICK_NEXT;
00130
00131 switch (msg.getType()) {
00132
00133 case NetworkMessage::FEDERATION_SYNCHRONIZED:
00134 try {
00135 fm->federationSynchronized(msg.getLabel().c_str());
00136 }
00137 catch (RTIinternalError &e) {
00138 cout << "RTIA:RTIinternalError in federationSynchronized." << endl ;
00139 throw e ;
00140 }
00141 break ;
00142
00143 case NetworkMessage::SYNCHRONIZATION_POINT_REGISTRATION_SUCCEEDED:
00144 try {
00145 fm->synchronizationPointRegistrationSucceeded(msg.getLabel().c_str());
00146 }
00147 catch (RTIinternalError &e) {
00148 cout << "RTIA:RTIinternalError in synchronizationPointRegistration"
00149 "Succeeded." << endl ;
00150 throw e ;
00151 }
00152 break ;
00153
00154 case NetworkMessage::ANNOUNCE_SYNCHRONIZATION_POINT:
00155 try {
00156 fm->announceSynchronizationPoint(msg.getLabel().c_str(), msg.getTag().c_str());
00157 }
00158 catch (RTIinternalError &e) {
00159 cout << "RTIA:RTIinternalError in announceSynchronizationPoint." << endl ;
00160 throw e ;
00161 }
00162 break ;
00163
00164 case NetworkMessage::DISCOVER_OBJECT:
00165 try {
00166 om->discoverObject(msg.object,
00167 msg.objectClass,
00168 msg.getLabel().c_str(),
00169 msg.getDate(),
00170 msg.eventRetraction,
00171 msg.exception);
00172
00173 }
00174 catch (RTIinternalError &e) {
00175 cout << "RTIA:RTIinternalError in discoverObject." << endl ;
00176 throw e ;
00177 }
00178 break ;
00179
00180 case NetworkMessage::REFLECT_ATTRIBUTE_VALUES:
00181 {
00182 std::vector<AttributeValue_t> ValueArray = msg.getAttribValueArray();
00183
00184 if (msg.isDated())
00185 om->reflectAttributeValues(msg.object,
00186 msg.handleArray,
00187 ValueArray,
00188 msg.handleArraySize,
00189 msg.getDate(),
00190 msg.getLabel().c_str(),
00191 msg.eventRetraction,
00192 msg.exception);
00193 else
00194 om->reflectAttributeValues(msg.object,
00195 msg.handleArray,
00196 ValueArray,
00197 msg.handleArraySize,
00198 msg.getLabel().c_str(),
00199 msg.exception);
00200 ValueArray.empty();
00201 break ;
00202 }
00203
00204 case NetworkMessage::PROVIDE_ATTRIBUTE_VALUE_UPDATE:
00205 {
00206 om->provideAttributeValueUpdate(msg.object,
00207 msg.handleArray,
00208 msg.handleArraySize,
00209 msg.exception);
00210 break;
00211 }
00212
00213
00214 case NetworkMessage::RECEIVE_INTERACTION:
00215 {
00216 std::vector<ParameterValue_t> ValueArray = msg.getParamValueArray();
00217
00218 if (msg.isDated())
00219 om->receiveInteraction(msg.interactionClass,
00220 msg.handleArray,
00221 ValueArray,
00222 msg.handleArraySize,
00223 msg.getDate(),
00224 msg.getLabel().c_str(),
00225 msg.eventRetraction,
00226 msg.exception);
00227 else
00228 om->receiveInteraction(msg.interactionClass,
00229 msg.handleArray,
00230 ValueArray,
00231 msg.handleArraySize,
00232 msg.getLabel().c_str(),
00233 msg.exception);
00234 ValueArray.empty();
00235
00236 break ;
00237 }
00238
00239 case NetworkMessage::REMOVE_OBJECT:
00240 if (msg.isDated()) {
00241 om->removeObject(msg.object,
00242 msg.federate,
00243 msg.getDate(),
00244 msg.getLabel().c_str(),
00245 msg.eventRetraction,
00246 msg.exception);
00247 }
00248 else {
00249 om->removeObject(msg.object,
00250 msg.federate,
00251 msg.getLabel().c_str(),
00252 msg.exception);
00253 }
00254 break ;
00255
00256 case NetworkMessage::INFORM_ATTRIBUTE_OWNERSHIP:
00257
00258 D.Out(pdInit, "m_REFLECT_ATTRIBUTE_VALUES Owner %u", msg.federate);
00259
00260 owm->informAttributeOwnership(msg.object,
00261 msg.handleArray[0],
00262 msg.federate,
00263 msg.exception);
00264 break ;
00265
00266 case NetworkMessage::ATTRIBUTE_IS_NOT_OWNED:
00267 owm->attributeIsNotOwned(msg.object,
00268 msg.handleArray[0],
00269 msg.federate,
00270 msg.exception);
00271 break ;
00272
00273 case NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION:
00274 {
00275 owm->requestAttributeOwnershipAssumption(msg.object,
00276 msg.handleArray,
00277 msg.handleArraySize,
00278 msg.federate,
00279 const_cast<char*>(msg.getLabel().c_str()),
00280 msg.exception);
00281 break ;
00282 }
00283
00284 case NetworkMessage::ATTRIBUTE_OWNERSHIP_UNAVAILABLE:
00285 {
00286 owm->attributeOwnershipUnavailable(msg.object,
00287 msg.handleArray,
00288 msg.handleArraySize,
00289 msg.federate,
00290 msg.exception);
00291 break ;
00292 }
00293
00294 case NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION:
00295 {
00296 owm->attributeOwnershipAcquisitionNotification(msg.object,
00297 msg.handleArray,
00298 msg.handleArraySize,
00299 msg.federate,
00300 msg.exception);
00301 break ;
00302 }
00303
00304 case NetworkMessage::ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION:
00305 {
00306 owm->attributeOwnershipDivestitureNotification(msg.object,
00307 msg.handleArray,
00308 msg.handleArraySize,
00309 msg.exception);
00310 break ;
00311 }
00312
00313 case NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_RELEASE:
00314 {
00315 owm->requestAttributeOwnershipRelease(msg.object,
00316 msg.handleArray,
00317 msg.handleArraySize,
00318 const_cast<char*>(msg.getLabel().c_str()),
00319 msg.exception);
00320 break ;
00321 }
00322
00323 case NetworkMessage::CONFIRM_ATTRIBUTE_OWNERSHIP_ACQUISITION_CANCELLATION:
00324 {
00325 owm->confirmAttributeOwnershipAcquisitionCancellation(msg.object,
00326 msg.handleArray,
00327 msg.handleArraySize,
00328 msg.exception);
00329 break ;
00330 }
00331
00332 case NetworkMessage::INITIATE_FEDERATE_SAVE:
00333 fm->initiateFederateSave(msg.getLabel().c_str());
00334 break ;
00335
00336 case NetworkMessage::FEDERATION_SAVED:
00337 case NetworkMessage::FEDERATION_NOT_SAVED: {
00338 bool status = (msg.getType() == NetworkMessage::FEDERATION_SAVED) ? true : false ;
00339 fm->federationSavedStatus(status);
00340 }
00341 break ;
00342
00343 case NetworkMessage::REQUEST_FEDERATION_RESTORE_SUCCEEDED:
00344 case NetworkMessage::REQUEST_FEDERATION_RESTORE_FAILED: {
00345 bool status = (msg.getType() == NetworkMessage::REQUEST_FEDERATION_RESTORE_SUCCEEDED)
00346 ? true : false ;
00347 fm->requestFederationRestoreStatus(status, msg.getLabel().c_str(), msg.getTag().c_str());
00348 }
00349 break ;
00350
00351 case NetworkMessage::FEDERATION_RESTORE_BEGUN:
00352 fm->federationRestoreBegun();
00353 break ;
00354
00355 case NetworkMessage::INITIATE_FEDERATE_RESTORE:
00356 fm->initiateFederateRestore(msg.getLabel().c_str(), msg.federate);
00357 break ;
00358
00359 case NetworkMessage::FEDERATION_RESTORED:
00360 case NetworkMessage::FEDERATION_NOT_RESTORED: {
00361 bool status = (msg.getType() == NetworkMessage::FEDERATION_RESTORED) ? true : false ;
00362 fm->federationRestoredStatus(status);
00363 }
00364 break ;
00365 case NetworkMessage::TIME_REGULATION_ENABLED:
00366 this->timeRegulationEnabled(msg.getDate(), msg.exception);
00367 break;
00368 case NetworkMessage::TIME_CONSTRAINED_ENABLED:
00369 this->timeConstrainedEnabled(msg.getDate(), msg.exception);
00370 break;
00371 case NetworkMessage::START_REGISTRATION_FOR_OBJECT_CLASS:
00372 dm->startRegistrationForObjectClass(msg.objectClass, msg.exception);
00373 break;
00374
00375 default:
00376 std::stringstream errorMsg;
00377 D.Out(pdExcept, "Unknown message type in executeFederateService.");
00378 errorMsg << "Unknown message <" << msg.getName() << " in executeFederateService.";
00379 throw RTIinternalError(errorMsg.str().c_str());
00380 }
00381 G.Out(pdGendoc,"exit TimeManagement::executeFederateService");
00382 return true ;
00383 }
00384
00385
00387 void
00388 TimeManagement::flushQueueRequest(FederationTime heure_logique,
00389 TypeException &e)
00390 {
00391 e = e_NO_EXCEPTION ;
00392
00393
00394 if (_avancee_en_cours != PAS_D_AVANCEE)
00395 e = e_TimeAdvanceAlreadyInProgress ;
00396
00397 if (heure_logique <= _heure_courante)
00398 e = e_FederationTimeAlreadyPassed ;
00399
00400 if (e == e_NO_EXCEPTION) {
00401
00402 D.Out(pdExcept, "flushQueueRequest not implemented.");
00403 throw RTIinternalError("flushQueueRequest not implemented.");
00404 }
00405 }
00406
00407
00412 void
00413 TimeManagement::nextEventAdvance(bool &msg_restant, TypeException &e)
00414 {
00415 FederationTime dateTSO ;
00416 FederationTime date_min = 0.0 ;
00417 bool TSOPresent ;
00418 bool msg_donne ;
00419 NetworkMessage *msg ;
00420
00421 G.Out(pdGendoc," enter TimeManagement::nextEventAdvance");
00422 msg_restant = false ;
00423
00424 if (_est_contraint) {
00425
00426
00427 queues->nextTsoDate(TSOPresent, dateTSO);
00428
00429 if ((TSOPresent) && (dateTSO < date_avancee))
00430 date_min = dateTSO ;
00431 else
00432 date_min = date_avancee ;
00433
00434 if (date_min < _LBTS) {
00435
00436
00437
00438
00439
00440
00441 date_avancee = date_min ;
00442
00443
00444 if (_est_regulateur)
00445 sendNullMessage(date_min);
00446
00447
00448
00449 msg = queues->giveTsoMessage(date_min, msg_donne, msg_restant);
00450 if (msg_donne) {
00451
00452 executeFederateService(*msg);
00453 delete msg ;
00454 }
00455 else {
00456
00457 timeAdvanceGrant(date_min, e);
00458 _avancee_en_cours = PAS_D_AVANCEE ;
00459 }
00460 }
00461 else {
00462
00463
00464
00465 if (_est_regulateur)
00466 sendNullMessage(_LBTS);
00467 }
00468 }
00469
00470 else {
00471
00472
00473
00474 if (_est_regulateur)
00475 sendNullMessage(date_avancee);
00476
00477 timeAdvanceGrant(date_avancee, e);
00478
00479 _avancee_en_cours = PAS_D_AVANCEE ;
00480 }
00481 G.Out(pdGendoc," exit TimeManagement::nextEventAdvance");
00482 }
00483
00484
00485 void
00486 TimeManagement::nextEventRequest(FederationTime heure_logique,
00487 TypeException &e)
00488 {
00489 e = e_NO_EXCEPTION ;
00490
00491
00492
00493 if (_avancee_en_cours != PAS_D_AVANCEE)
00494 e = e_TimeAdvanceAlreadyInProgress ;
00495
00496 if (heure_logique < _heure_courante)
00497 e = e_FederationTimeAlreadyPassed ;
00498
00499 if (heure_logique < _heure_courante + _lookahead_courant)
00500 e = e_InvalidFederationTime ;
00501
00502 if (e == e_NO_EXCEPTION) {
00503
00504 _type_granted_state = AFTER_TAR_OR_NER ;
00505
00506 if (_lookahead_courant == 0.0) {
00507 _lookahead_courant == epsilon2 ;
00508 _type_granted_state = AFTER_TAR_OR_NER_WITH_ZERO_LK ;
00509 }
00510
00511 _avancee_en_cours = NER ;
00512 date_avancee = heure_logique ;
00513 D.Out(pdTrace, "NextEventRequest accepted.");
00514 }
00515 else {
00516 D.Out(pdExcept, "NextEventRequest refused (exception = %d).", e);
00517 }
00518 }
00519
00520
00521 void
00522 TimeManagement::nextEventRequestAvailable(FederationTime heure_logique,
00523 TypeException &e)
00524 {
00525 e = e_NO_EXCEPTION ;
00526
00527
00528
00529 if (_avancee_en_cours != PAS_D_AVANCEE)
00530 e = e_TimeAdvanceAlreadyInProgress ;
00531
00532 if (heure_logique < _heure_courante)
00533 e = e_FederationTimeAlreadyPassed ;
00534
00535 if (heure_logique < _heure_courante + _lookahead_courant)
00536 e = e_InvalidFederationTime ;
00537
00538 if (e == e_NO_EXCEPTION) {
00539 _type_granted_state = AFTER_TARA_OR_NERA ;
00540 _avancee_en_cours = NERA ;
00541 date_avancee = heure_logique ;
00542 D.Out(pdTrace, "NextEventRequestAvailable accepted.");
00543 }
00544 else {
00545 D.Out(pdExcept, "NextEventRequestAvailable refused (exception = %d).", e);
00546 }
00547 }
00548
00549
00550 FederationTime
00551 TimeManagement::requestFederationTime()
00552 {
00553 return _LBTS ;
00554 }
00555
00556
00557 FederationTimeDelta TimeManagement::requestLookahead()
00558 {
00559 return _lookahead_courant ;
00560 }
00561
00562
00564 FederationTime
00565 TimeManagement::requestMinNextEventTime()
00566 {
00567 FederationTime dateTSO ;
00568 FederationTime dateMNET ;
00569 bool found ;
00570
00571 queues->nextTsoDate(found, dateTSO) ;
00572
00573 if (!found)
00574 dateMNET = _LBTS ;
00575 else
00576 dateMNET = (_LBTS <= dateTSO ? _LBTS : dateTSO) ;
00577
00578 D.Out(pdRegister, "Minimum Next Event Time : %f.", dateMNET.getTime());
00579
00580 return dateMNET ;
00581 }
00582
00583
00584 void
00585 TimeManagement::setLookahead(FederationTimeDelta lookahead, TypeException &e)
00586 {
00587 e = e_NO_EXCEPTION ;
00588
00589
00590
00591 if (lookahead < 0.0)
00592 e = e_InvalidLookahead ;
00593
00594 if (lookahead == epsilon2) {
00595 cout << "Bad value of lookahead due to a zero lookahead implementation trick" << endl;
00596 e = e_RTIinternalError ;
00597 }
00598
00599 if (e == e_NO_EXCEPTION) {
00600 _lookahead_courant = lookahead ;
00601
00602
00603
00604 if (_est_regulateur)
00605 sendNullMessage(_heure_courante);
00606
00607 D.Out(pdRegister, "New Lookahead : %f.", _lookahead_courant.getTime());
00608 }
00609 }
00610
00611
00612 void
00613 TimeManagement::setTimeConstrained(bool etat, TypeException &e)
00614 {
00615 NM_Set_Time_Constrained msg ;
00616
00617 e = e_NO_EXCEPTION ;
00618
00619
00620
00621 if (_est_contraint == etat)
00622 e = e_RTIinternalError ;
00623
00624 if (_avancee_en_cours != PAS_D_AVANCEE)
00625 e = e_RTIinternalError ;
00626
00627 if (e == e_NO_EXCEPTION) {
00628 _est_contraint = etat ;
00629
00630 msg.federation = fm->_numero_federation ;
00631 msg.federate = fm->federate ;
00632 if (etat) {
00633 msg.constrainedOn();
00634 } else {
00635 msg.constrainedOff();
00636 }
00637
00638 comm->sendMessage(&msg);
00639
00640 D.Out(pdRegister,
00641 "Demande de modif de TimeConstrained envoyee(etat=%d, ", etat);
00642 }
00643 else {
00644 D.Out(pdExcept, "SetTimeConstrained refuse(exception = %d).", e);
00645 }
00646 }
00647
00648
00649
00650
00651 void
00652 TimeManagement::setTimeRegulating(bool etat,FederationTime heure_logique,
00653 FederationTimeDelta the_lookahead, TypeException &e)
00654 {
00655 NM_Set_Time_Regulating msg ;
00656
00657 e = e_NO_EXCEPTION ;
00658
00659
00660
00661 if (_est_regulateur == etat) {
00662 e = e_RTIinternalError ;
00663 D.Out(pdRegister,
00664 "erreur e_RTIinternalError : federe deja regulateur");
00665 }
00666
00667 if (_avancee_en_cours != PAS_D_AVANCEE) {
00668 e = e_RTIinternalError ;
00669 D.Out(pdRegister, "erreur e_RTIinternalError avancee_en_cours");
00670 }
00671
00672
00673 if (e == e_NO_EXCEPTION) {
00674 _est_regulateur = etat ;
00675
00676 msg.federation = fm->_numero_federation ;
00677 msg.federate = fm->federate ;
00678 if (etat) {
00679 msg.regulatorOn();
00680 D.Out(pdDebug,
00681 "REGULATOR ON");
00682 } else {
00683 msg.regulatorOff();
00684 D.Out(pdDebug,
00685 "REGULATOR OFF");
00686 }
00687
00688 _lookahead_courant = the_lookahead;
00689 D.Out(pdDebug,
00690 "New lookahead = %f",_lookahead_courant.getTime());
00691
00692 msg.setDate(_heure_courante + _lookahead_courant);
00693
00694 comm->sendMessage(&msg);
00695
00696 D.Out(pdRegister,
00697 "Demande de modif de TimeRegulating emise(etat=%d).", etat);
00698 }
00699 else {
00700 D.Out(pdExcept, "SetTimeRegulating refuse(exception = %d).", e);
00701 }
00702 }
00703
00704
00705 void
00706 TimeManagement::timeRegulationEnabled(FederationTime theTime, TypeException &e) {
00707 Message req;
00708
00709 D.Out(pdDebug,"Sending TIME_REGULATION_ENABLED to Federate");
00710 req.type = Message::TIME_REGULATION_ENABLED;
00711 req.setFederationTime(theTime);
00712 comm->requestFederateService(&req);
00713 }
00714
00715
00716 void
00717 TimeManagement::timeConstrainedEnabled(FederationTime theTime, TypeException &e) {
00718 Message req;
00719
00720 D.Out(pdDebug,"Sending TIME_CONSTRAINED_ENABLED to Federate");
00721 req.type = Message::TIME_CONSTRAINED_ENABLED;
00722 req.setFederationTime(theTime);
00723 comm->requestFederateService(&req);
00724 }
00725
00726
00729 bool
00730 TimeManagement::testValidTime(FederationTime theTime)
00731 {
00732 if (_avancee_en_cours == PAS_D_AVANCEE) {
00733 if (_type_granted_state == AFTER_TAR_OR_NER_WITH_ZERO_LK) {
00734 if (theTime <= _heure_courante)
00735 return false;
00736 }
00737 else {
00738 if (theTime < _heure_courante + _lookahead_courant)
00739 return false;
00740 }
00741 }
00742 else {
00743 if (_type_granted_state == AFTER_TAR_OR_NER_WITH_ZERO_LK) {
00744 if (theTime <= date_avancee)
00745 return false;
00746 }
00747 else {
00748 if (theTime < date_avancee + _lookahead_courant)
00749 return false;
00750 }
00751 }
00752 return true;
00753 }
00754
00755
00760 bool
00761 TimeManagement::tick(TypeException &e)
00762 {
00763 bool msg_donne = false ;
00764 bool msg_restant = false ;
00765 NetworkMessage *msg = NULL ;
00766
00767 G.Out(pdGendoc," enter TimeManagement::tick");
00768
00769
00770
00771 msg = queues->giveCommandMessage(msg_donne, msg_restant);
00772
00773
00774 if (!msg_donne){
00775 if ( _asynchronous_delivery || (_avancee_en_cours != PAS_D_AVANCEE) || (! _est_contraint)) {
00776 D.Out(pdDebug,"FIFO message to be delivered async_deliver=%d, _avancee=%d, constrained=%d",
00777 _asynchronous_delivery,_avancee_en_cours,_est_contraint);
00778
00779
00780 msg = queues->giveFifoMessage(msg_donne, msg_restant);
00781 } else {
00782 D.Out(pdDebug,"FIFO message skipped async_deliver=%d, _avancee=%d, constrained=%d",
00783 _asynchronous_delivery,_avancee_en_cours,_est_contraint);
00784 }
00785 }
00786
00787
00788 if (msg_donne) {
00789 D.Out(pdDebug, "TickRequest being processed, Message to send.");
00790 try {
00791 executeFederateService(*msg);
00792 }
00793 catch (RTIinternalError &e) {
00794 cout << "RTIA:RTIinternalError thrown in tick (execute)." << endl ;
00795 throw e ;
00796 }
00797 }
00798
00799
00800
00801 else {
00802 D.Out(pdDebug, "TickRequest being processed, advance called.");
00803 try {
00804 advance(msg_restant, e);
00805 }
00806 catch (RTIinternalError &e) {
00807 cout << "RTIA:RTIinternalError thrown in tick (Advance)." << endl ;
00808 throw e ;
00809 }
00810 }
00811
00812 delete msg ;
00813
00814 G.Out(pdGendoc," exit TimeManagement::tick");
00815 return msg_restant ;
00816 }
00817
00818
00823 void
00824 TimeManagement::timeAdvance(bool &msg_restant, TypeException &e)
00825 {
00826 bool msg_donne ;
00827 FederationTime min ;
00828 NetworkMessage *msg ;
00829 G.Out(pdGendoc," enter TimeManagement::timeAdvance");
00830 msg_restant = false ;
00831
00832 if (_est_contraint) {
00833
00834 if (_LBTS == std::numeric_limits<double>::infinity())
00835 D.Out(pdDebug, "Logical time : %f, LBTS : infini.", date_avancee.getTime());
00836 else
00837 D.Out(pdDebug, "Logical time : %f, LBTS : %lf.", date_avancee.getTime(), _LBTS.getTime());
00838 min = (_LBTS<date_avancee)?(_LBTS):(date_avancee);
00839 msg = queues->giveTsoMessage(min, msg_donne, msg_restant);
00840
00841
00842 if (!msg_donne) {
00843
00844 if (_LBTS == std::numeric_limits<double>::infinity())
00845 D.Out(pdDebug, "Logical time : %f, LBTS : infini, lookahead : %f.",
00846 date_avancee.getTime(), _lookahead_courant.getTime());
00847 else
00848 D.Out(pdDebug, "Logical time : %15.12f, LBTS : %15.12f, lookahead : %f.",
00849 date_avancee.getTime(), _LBTS.getTime(), _lookahead_courant.getTime());
00850
00851 if ((date_avancee < _LBTS) ||
00852 ((date_avancee == _LBTS) && (_avancee_en_cours == TARA))) {
00853
00854 timeAdvanceGrant(date_avancee, e);
00855
00856 if (e != e_NO_EXCEPTION)
00857 return ;
00858
00859 _avancee_en_cours = PAS_D_AVANCEE ;
00860 }
00861
00862 }
00863 else {
00864 executeFederateService(*msg);
00865 delete msg ;
00866 }
00867 }
00868 else {
00869
00870 timeAdvanceGrant(date_avancee, e);
00871 if (e != e_NO_EXCEPTION)
00872 return ;
00873 _avancee_en_cours = PAS_D_AVANCEE ;
00874 }
00875 G.Out(pdGendoc," exit TimeManagement::timeAdvance");
00876 }
00877
00878
00882 void
00883 TimeManagement::timeAdvanceGrant(FederationTime logical_time,
00884 TypeException &e)
00885 {
00886 Message req;
00887
00888 req.type = Message::TIME_ADVANCE_GRANT ;
00889 req.setFederationTime(logical_time);
00890
00891 D.Out(pdRegister, "timeAdvanceGrant sent to federate (time = %f).",
00892 req.getFederationTime().getTime());
00893
00894 if (_lookahead_courant == epsilon2)
00895 _lookahead_courant = 0.0 ;
00896
00897 _tick_state = TICK_NEXT;
00898
00899 comm->requestFederateService(&req);
00900
00901 _heure_courante = logical_time ;
00902 }
00903
00904
00909 void
00910 TimeManagement::timeAdvanceRequest(FederationTime logical_time,
00911 TypeException &e)
00912 {
00913 e = e_NO_EXCEPTION ;
00914
00915
00916
00917 if (_avancee_en_cours != PAS_D_AVANCEE)
00918 e = e_TimeAdvanceAlreadyInProgress ;
00919
00920 if (logical_time < _heure_courante)
00921 e = e_FederationTimeAlreadyPassed ;
00922
00923 if (logical_time < _heure_courante + _lookahead_courant) {
00924
00925 D.Out(pdDebug,"InvalidFederation time lkahead=%f, current=%f, requested=%f",
00926 _lookahead_courant.getTime(),_heure_courante.getTime(),logical_time.getTime());
00927 e = e_InvalidFederationTime ;
00928 }
00929
00930 if (e == e_NO_EXCEPTION) {
00931
00932 _type_granted_state = AFTER_TAR_OR_NER ;
00933
00934 if (_lookahead_courant == 0.0) {
00935 _lookahead_courant = epsilon2 ;
00936 _type_granted_state = AFTER_TAR_OR_NER_WITH_ZERO_LK ;
00937 }
00938
00939 if (_est_regulateur)
00940 sendNullMessage(logical_time);
00941
00942 _avancee_en_cours = TAR ;
00943 date_avancee = logical_time ;
00944
00945 D.Out(pdTrace, "timeAdvanceRequest accepted (asked time=%f).",
00946 date_avancee.getTime());
00947 }
00948 else {
00949 D.Out(pdExcept, "timeAdvanceRequest refused (exception = %d).", e);
00950 }
00951 }
00952
00953
00954 void
00955 TimeManagement::timeAdvanceRequestAvailable(FederationTime logical_time,
00956 TypeException &e)
00957 {
00958 e = e_NO_EXCEPTION ;
00959
00960
00961
00962 if (_avancee_en_cours != PAS_D_AVANCEE)
00963 e = e_TimeAdvanceAlreadyInProgress ;
00964
00965 if (logical_time < _heure_courante)
00966 e = e_FederationTimeAlreadyPassed ;
00967
00968 if (logical_time < _heure_courante + _lookahead_courant)
00969 e = e_InvalidFederationTime ;
00970
00971 if (e == e_NO_EXCEPTION) {
00972
00973 _type_granted_state = AFTER_TARA_OR_NERA ;
00974
00975 if (_est_regulateur)
00976 sendNullMessage(logical_time);
00977
00978 _avancee_en_cours = TARA ;
00979 date_avancee = logical_time ;
00980
00981 D.Out(pdTrace, "timeAdvanceRequestAvailable accepted (asked time=%f).",
00982 date_avancee.getTime());
00983 }
00984 else {
00985 D.Out(pdExcept, "timeAdvanceRequestAvailable refused (exception = %d).", e);
00986 }
00987 }
00988
00989
00990 }}
00991
00992