00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "Interaction.hh"
00028 #include "InteractionSet.hh"
00029 #include "InteractionBroadcastList.hh"
00030 #include "PrettyDebug.hh"
00031 #include "NM_Classes.hh"
00032
00033 #include <iostream>
00034 #include <sstream>
00035 #include <assert.h>
00036
00037 using std::cout ;
00038 using std::endl ;
00039 using std::list ;
00040
00041 namespace certi {
00042
00043 static pdCDebug D("INTERACTION", "(Interact) - ");
00044 static PrettyDebug G("GENDOC",__FILE__) ;
00045
00046 Interaction::Interaction(const std::string& theName, InteractionClassHandle theHandle, TransportType theTransport, OrderType theOrder)
00047 : parent(0), depth(0), transport(theTransport), order(theOrder), handle(theHandle),
00048 id(PublicLevelID)
00049 {
00050 setName(theName);
00051
00052
00053
00054 subClasses = new InteractionSet(NULL);
00055 }
00056
00057 Interaction::~Interaction()
00058 {
00059 while (!parameterSet.empty()) {
00060 delete parameterSet.front();
00061 parameterSet.pop_front();
00062 }
00063
00064 if (!publishers.empty())
00065 D.Out(pdError, "Interaction %d: publishers list not empty at termination.", handle);
00066
00067
00068 if (NULL!=subClasses) {
00069 delete subClasses;
00070 }
00071 }
00072
00073 void Interaction::addSubClass(Interaction *child) {
00074
00075
00076 subClasses->addClass(child,NULL);
00077
00078 child->superClass = handle;
00079
00080
00081 addInheritedClassParameter(child);
00082
00083 child->server = server;
00084
00085 child->setSecurityLevelId(id);
00086 }
00087
00088
00090 ParameterHandle
00091 Interaction::addParameter(Parameter *the_parameter, bool is_inherited)
00092 {
00093
00094
00095
00096
00097
00098
00099
00100 if (!is_inherited)
00101 the_parameter->LevelID = id ;
00102
00103 parameterSet.push_front(the_parameter);
00104
00105 D[pdRegister] << "Interaction " << handle << "[" << name.c_str()
00106 << "] has a new parameter "
00107 << the_parameter->getHandle() << "[" << the_parameter->getName().c_str() << "]"
00108 << std::flush;
00109
00110 return the_parameter->getHandle();
00111 }
00112
00113 void
00114 Interaction::addInheritedClassParameter(Interaction *the_child)
00115 {
00116
00117
00118 Parameter *child = NULL ;
00119 list<Parameter *>::reverse_iterator it ;
00120 for (it = parameterSet.rbegin(); it != parameterSet.rend(); it++) {
00121 assert((*it) != NULL);
00122
00123 child = new Parameter(**it);
00124 assert(child != NULL);
00125
00126 D.Out(pdProtocol,
00127 "ObjectClass %u adding new parameter %d to child class %u.",
00128 handle, (*it)->getHandle(), the_child->handle);
00129
00130 the_child->addParameter(child, true);
00131
00132
00133 if (child->getHandle() != (*it)->getHandle()) {
00134 throw RTIinternalError("Error while copying child's attributes.");
00135 } else {
00136 ;
00137 }
00138 }
00139 }
00140
00141
00147 void
00148 Interaction::broadcastInteractionMessage(InteractionBroadcastList *ibList,
00149 const RTIRegion *region)
00150 {
00151
00152 G.Out(pdGendoc,"enter Interaction::broadcastInteractionMessage");
00153
00154
00155 ibList->message->interactionClass = handle ;
00156
00157
00158 for (int i = 0 ; i < ibList->message->handleArraySize ;) {
00159
00160 try {
00161 getParameterByHandle(ibList->message->handleArray[i]);
00162 i++ ;
00163 }
00164 catch (InteractionParameterNotDefined) {
00165 ibList->message->removeParameter(i);
00166 }
00167 }
00168
00169
00170 addFederatesIfOverlap(*ibList, region);
00171
00172
00173 D.Out(pdDebug, "Calling SendPendingMessage...");
00174 ibList->sendPendingMessage(server);
00175
00176 G.Out(pdGendoc,"exit Interaction::broadcastInteractionMessage");
00177
00178 }
00179
00180
00182 void
00183 Interaction::changeTransportationType(TransportType new_type,
00184 FederateHandle the_handle)
00185 throw (FederateNotPublishing,
00186 InvalidTransportationHandle,
00187 RTIinternalError)
00188 {
00189 if (!isPublishing(the_handle))
00190 throw FederateNotPublishing("Change Interaction Transport Type.");
00191
00192 if ((new_type != RELIABLE) && (new_type != BEST_EFFORT))
00193 throw InvalidTransportationHandle("");
00194
00195 transport = new_type ;
00196
00197 D.Out(pdInit,
00198 "Interaction %d: New Transport type is %d.", handle, transport);
00199 }
00200
00201
00203 void
00204 Interaction::changeOrderType(OrderType new_order, FederateHandle the_handle)
00205 throw (FederateNotPublishing,
00206 InvalidOrderingHandle,
00207 RTIinternalError)
00208 {
00209 if (!isPublishing(the_handle))
00210 throw FederateNotPublishing("Change Interaction Order Type.");
00211
00212 if ((new_order != RECEIVE) && (new_order != TIMESTAMP))
00213 throw InvalidOrderingHandle("");
00214
00215 D.Out(pdInit, "Interaction %d: New Order type is %d.", handle, order);
00216 }
00217
00218
00222 void
00223 Interaction::checkFederateAccess(FederateHandle the_federate,
00224 const char *reason) const
00225 throw (SecurityError)
00226 {
00227
00228 if (server == NULL)
00229 return ;
00230
00231 bool result = server->canFederateAccessData(the_federate, id);
00232
00233
00234 if (!result) {
00235 cout << "Interaction " << handle << " : SecurityError for federate "
00236 << the_federate << '(' << reason << ")." << endl ;
00237 throw SecurityError("Federate should not access Interaction.");
00238 }
00239 }
00240
00241
00243 void
00244 Interaction::deletePublisher(FederateHandle fed)
00245 {
00246 PublishersList::iterator it = publishers.find(fed);
00247 if (it != publishers.end())
00248 publishers.erase(it);
00249 }
00250
00251
00253 void
00254 Interaction::display() const
00255 {
00256 cout << " Interaction " << handle << " \"" << name << "\" :" << endl ;
00257
00258
00259 cout << " Parent Class Handle: " << parent << endl ;
00260 cout << " Security Level: " << id << endl ;
00261 cout << " " << subClasses->size() << " Child(s):" << endl ;
00262
00263
00264
00265
00266
00267
00268
00269
00270 cout << " " << parameterSet.size() << " Parameters:" << endl ;
00271
00272 list<Parameter *>::const_iterator p = parameterSet.begin();
00273 for (; p != parameterSet.end(); p++) {
00274 (*p)->display();
00275 }
00276 }
00277
00278
00280 Parameter*
00281 Interaction::getParameterByHandle(ParameterHandle the_handle) const
00282 throw (InteractionParameterNotDefined, RTIinternalError)
00283 {
00284 list<Parameter *>::const_iterator p ;
00285 for (p = parameterSet.begin(); p != parameterSet.end(); p++) {
00286 if ((*p)->getHandle() == the_handle)
00287 return (*p);
00288 }
00289
00290 throw InteractionParameterNotDefined("");
00291 }
00292
00293
00295 ParameterHandle
00296 Interaction::getParameterHandle(const char *the_name) const
00297 throw (NameNotFound, RTIinternalError)
00298 {
00299 list<Parameter *>::const_iterator p ;
00300 for (p = parameterSet.begin(); p != parameterSet.end(); p++) {
00301 if ((*p)->getName() == the_name)
00302 return (*p)->getHandle();
00303 }
00304
00305 throw NameNotFound("");
00306 }
00307
00308
00309
00310 const std::string&
00311 Interaction::getParameterName(ParameterHandle the_handle) const
00312 throw (InteractionParameterNotDefined,
00313 RTIinternalError)
00314 {
00315 return getParameterByHandle(the_handle)->getName();
00316 }
00317
00318
00320 bool
00321 Interaction::isPublishing(FederateHandle fed)
00322 {
00323 return publishers.find(fed) != publishers.end();
00324 }
00325
00326
00330 void
00331 Interaction::isReady(FederateHandle federate_handle,
00332 std::vector <ParameterHandle> ¶meter_list,
00333 UShort list_size)
00334 throw (FederateNotPublishing,
00335 InteractionParameterNotDefined,
00336 RTIinternalError)
00337 {
00338
00339 if (!isPublishing(federate_handle))
00340 throw FederateNotPublishing("");
00341
00342
00343 for (UShort i = 0 ; i < list_size ; i++)
00344 getParameterByHandle(parameter_list[i]);
00345 }
00346
00347
00349 void
00350 Interaction::killFederate(FederateHandle the_federate)
00351 throw ()
00352 {
00353 try {
00354
00355 if (isPublishing(the_federate))
00356 unpublish(the_federate);
00357
00358
00359 if (isSubscribed(the_federate))
00360 unsubscribe(the_federate);
00361 }
00362 catch (SecurityError &e) {}
00363 }
00364
00365
00367 void
00368 Interaction::publish(FederateHandle the_handle)
00369 throw (FederateNotPublishing, RTIinternalError, SecurityError)
00370 {
00371 checkFederateAccess(the_handle, (char *) "Publish");
00372
00373 if (!isPublishing(the_handle)) {
00374 D.Out(pdInit, "Interaction %d: Added Federate %d to publishers list.", handle, the_handle);
00375 publishers.insert(the_handle);
00376 }
00377 else
00378 D.Out(pdError, "Interaction %d: Inconsistent publish request from Federate %d.", handle, the_handle);
00379 }
00380
00381
00383 void
00384 Interaction::unpublish(FederateHandle the_handle)
00385 throw (FederateNotPublishing, RTIinternalError, SecurityError)
00386 {
00387 if (isPublishing(the_handle)) {
00388 D.Out(pdTerm,
00389 "Interaction %d: Removed Federate %d from publishers list.",
00390 handle, the_handle);
00391 deletePublisher(the_handle);
00392 }
00393 else {
00394 throw FederateNotPublishing("");
00395 }
00396 }
00397
00398
00403 InteractionBroadcastList *
00404 Interaction::sendInteraction(FederateHandle federate_handle,
00405 std::vector <ParameterHandle> ¶meter_list,
00406 std::vector <ParameterValue_t> &value_list,
00407 UShort list_size,
00408 FederationTime time,
00409 const RTIRegion *region,
00410 const char *the_tag)
00411 throw (FederateNotPublishing,
00412 InteractionClassNotDefined,
00413 InteractionParameterNotDefined,
00414 RTIinternalError)
00415 {
00416
00417 G.Out(pdGendoc,"enter Interaction::sendInteraction with time");
00418
00419
00420 if (!isPublishing(federate_handle))
00421 throw FederateNotPublishing("");
00422
00423
00424 InteractionBroadcastList *ibList = NULL ;
00425 if (server != NULL) {
00426 NetworkMessage *answer = NM_Factory::create(NetworkMessage::RECEIVE_INTERACTION) ;
00427 answer->exception = e_NO_EXCEPTION ;
00428 answer->federation = server->federation();
00429 answer->federate = federate_handle ;
00430 answer->interactionClass = handle ;
00431 answer->setDate(time);
00432
00433 answer->setLabel(the_tag);
00434
00435 answer->handleArraySize = list_size ;
00436 answer->handleArray.resize(list_size) ;
00437 answer->sizeValueArray(list_size);
00438 for (int i = 0 ; i < list_size ; i++) {
00439 answer->handleArray[i] = parameter_list[i] ;
00440 answer->valueArray[i] = value_list[i];
00441 }
00442
00443 D.Out(pdProtocol, "Preparing broadcast list.");
00444 ibList = new InteractionBroadcastList(answer);
00445
00446 broadcastInteractionMessage(ibList, region);
00447 }
00448 else
00449
00450 throw RTIinternalError("SendInteraction called by RTIA.");
00451
00452 G.Out(pdGendoc,"exit Interaction::sendInteraction with time");
00453
00454
00455
00456 return ibList ;
00457 }
00458
00459
00464 InteractionBroadcastList *
00465 Interaction::sendInteraction(FederateHandle federate_handle,
00466 std::vector <ParameterHandle> ¶meter_list,
00467 std::vector <ParameterValue_t> &value_list,
00468 UShort list_size,
00469 const RTIRegion *region,
00470 const char *the_tag)
00471 throw (FederateNotPublishing,
00472 InteractionClassNotDefined,
00473 InteractionParameterNotDefined,
00474 RTIinternalError)
00475 {
00476
00477 G.Out(pdGendoc,"enter Interaction::sendInteraction without time");
00478
00479
00480 if (!isPublishing(federate_handle))
00481 throw FederateNotPublishing("");
00482
00483
00484 InteractionBroadcastList *ibList = NULL ;
00485 if (server != NULL) {
00486 NetworkMessage *answer = NM_Factory::create(NetworkMessage::RECEIVE_INTERACTION) ;
00487 answer->exception = e_NO_EXCEPTION ;
00488 answer->federation = server->federation();
00489 answer->federate = federate_handle ;
00490 answer->interactionClass = handle ;
00491 answer->setLabel(the_tag);
00492
00493 answer->handleArraySize = list_size ;
00494 answer->handleArray.resize(list_size) ;
00495 answer->sizeValueArray(list_size);
00496
00497 for (int i = 0 ; i < list_size ; i++) {
00498 answer->handleArray[i] = parameter_list[i] ;
00499 answer->valueArray[i] = value_list[i];
00500 }
00501
00502 D.Out(pdProtocol, "Preparing broadcast list.");
00503 ibList = new InteractionBroadcastList(answer);
00504
00505 broadcastInteractionMessage(ibList, region);
00506 }
00507 else
00508
00509 throw RTIinternalError("SendInteraction called by RTIA.");
00510
00511 G.Out(pdGendoc,"exit Interaction::sendInteraction without time");
00512
00513
00514
00515 return ibList ;
00516 }
00517
00518
00519
00521
00523 void
00524 Interaction::setSecurityLevelId(SecurityLevelID new_levelID)
00525 {
00526 if (!server->dominates(new_levelID, id))
00527 throw SecurityError("Attempt to lower interaction class level.");
00528
00529 id = new_levelID ;
00530 }
00531
00532
00533
00534 void
00535 Interaction::setSpace(SpaceHandle h)
00536 {
00537 space = h ;
00538 }
00539
00540
00541
00542 SpaceHandle
00543 Interaction::getSpace()
00544 {
00545 return space ;
00546 }
00547
00548 }
00549
00550