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 #include "Object.hh"
00026 #include "ObjectAttribute.hh"
00027 #include "ObjectClass.hh"
00028 #include "ObjectClassAttribute.hh"
00029 #include "ObjectClassSet.hh"
00030 #include "ObjectClassBroadcastList.hh"
00031 #include "NM_Classes.hh"
00032
00033 #include "SocketTCP.hh"
00034 #include "PrettyDebug.hh"
00035 #include "helper.hh"
00036 #include <sstream>
00037 #include <memory>
00038
00039 #ifdef _WIN32
00040 #include <windows.h>
00041 #include <algorithm>
00042 #ifdef max
00043 #undef max
00044 #endif
00045 #else
00046 #include <iostream>
00047 #endif
00048 #include <assert.h>
00049
00050 using std::cout ;
00051 using std::endl ;
00052 using std::list ;
00053
00054 namespace certi {
00055
00056 static pdCDebug D("OBJECTCLASS", __FILE__);
00057 static PrettyDebug G("GENDOC",__FILE__);
00058
00059
00061 AttributeHandle
00062 ObjectClass::addAttribute(ObjectClassAttribute *theAttribute,
00063 bool is_inherited)
00064 {
00065 if (theAttribute == NULL)
00066 throw RTIinternalError("Tried to add NULL attribute.");
00067
00068 theAttribute->setHandle(attributeSet.size() + 1);
00069 theAttribute->server = server ;
00070
00071
00072
00073 if (!is_inherited)
00074 theAttribute->level = securityLevelId ;
00075
00076 attributeSet.push_front(theAttribute);
00077
00078 D.Out(pdProtocol, "ObjectClass %u has a new attribute %u.",
00079 handle, theAttribute->getHandle());
00080
00081 return theAttribute->getHandle();
00082 }
00083
00084
00086 void
00087 ObjectClass::addInheritedClassAttributes(ObjectClass *the_child)
00088 {
00089
00090
00091 ObjectClassAttribute *childAttribute = NULL ;
00092 list<ObjectClassAttribute *>::reverse_iterator a ;
00093 for (a = attributeSet.rbegin(); a != attributeSet.rend(); a++) {
00094 assert((*a) != NULL);
00095
00096 childAttribute = new ObjectClassAttribute(*a);
00097 assert(childAttribute != NULL);
00098
00099 D.Out(pdProtocol,
00100 "ObjectClass %u adding new attribute %d to child class %u.",
00101 handle, (*a)->getHandle(), the_child->getHandle());
00102
00103 the_child->addAttribute(childAttribute);
00104
00105 if (childAttribute->getHandle() != (*a)->getHandle())
00106 throw RTIinternalError("Error while copying child's attributes.");
00107 }
00108 }
00109
00110
00115 void
00116 ObjectClass::broadcastClassMessage(ObjectClassBroadcastList *ocbList,
00117 const Object *source)
00118 {
00119 int i, trouve;
00120 G.Out(pdGendoc,"enter ObjectClass::broadcastClassMessage");
00121
00122 ocbList->message->objectClass = handle ;
00123
00124 G.Out(pdGendoc," ObjectClass::broadcastClassMessage handle=%d",handle);
00125
00126
00127 if ((ocbList->message->getType() == NetworkMessage::REFLECT_ATTRIBUTE_VALUES) ||
00128 (ocbList->message->getType() == NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION)) {
00129 int attr = 0 ;
00130 while (attr < ocbList->message->handleArraySize) {
00131
00132
00133 try {
00134 getAttribute(ocbList->message->handleArray[attr]);
00135 attr++ ;
00136 }
00137 catch (AttributeNotDefined &e) {
00138 ocbList->message->removeAttribute(attr);
00139 }
00140 }
00141 }
00142
00143
00144 switch(ocbList->message->getType()) {
00145 case NetworkMessage::DISCOVER_OBJECT:
00146 case NetworkMessage::REMOVE_OBJECT: {
00147
00148
00149 FederateHandle federate = 0 ;
00150 for (federate = 1 ; federate <= maxSubscriberHandle ; federate++) {
00151 if (isSubscribed(federate) && (federate != ocbList->message->federate)) {
00152 ocbList->addFederate(federate);
00153 }
00154 }
00155 } break ;
00156
00157 case NetworkMessage::REFLECT_ATTRIBUTE_VALUES: {
00158
00159
00160 list<ObjectClassAttribute *>::const_iterator a ;
00161 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00162
00163 trouve = 0;
00164 for (i=0 ; i< ocbList->message->handleArraySize ; i++) {
00165 if ((*a)->getHandle() == ocbList->message->handleArray[i])
00166 trouve = 1;
00167 }
00168 if (trouve) {
00169 ObjectAttribute *attr = source->getAttribute((*a)->getHandle());
00170 const RTIRegion *update_region = attr->getRegion();
00171 D[pdTrace] << "RAV: attr " << (*a)->getHandle()
00172 << " / region " << (update_region ? update_region->getHandle() : 0)
00173 << std::endl ;
00174 (*a)->updateBroadcastList(ocbList, update_region);
00175 }
00176 }
00177 } break ;
00178
00179 case NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION: {
00180
00181
00182 list<ObjectClassAttribute *>::const_iterator a ;
00183 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00184 (*a)->updateBroadcastList(ocbList);
00185 }
00186 } break ;
00187
00188 default:
00189 throw RTIinternalError("BroadcastClassMsg: Unknown type.");
00190 }
00191
00192
00193 ocbList->sendPendingMessage(server);
00194 G.Out(pdGendoc,"exit ObjectClass::broadcastClassMessage");
00195 }
00196
00197
00199 void
00200 ObjectClass::sendToFederate(NetworkMessage *msg, FederateHandle theFederate)
00201 {
00202
00203 Socket *socket = NULL ;
00204 try {
00205 #ifdef HLA_USES_UDP
00206 socket = server->getSocketLink(theFederate, BEST_EFFORT);
00207 #else
00208 socket = server->getSocketLink(theFederate);
00209 #endif
00210 msg->send(socket,NM_msgBufSend);
00211 }
00212 catch (RTIinternalError &e) {
00213 D.Out(pdExcept,
00214 "Reference to a killed Federate while broadcasting.");
00215 }
00216 catch (NetworkError &e) {
00217 D.Out(pdExcept, "Network error while broadcasting, ignoring.");
00218 }
00219
00220 }
00221
00222
00224 void
00225 ObjectClass::sendToOwners(CDiffusion *diffusionList,
00226 ObjectHandle theObjectHandle,
00227 FederateHandle theFederate,
00228 const char *theTag,
00229 NetworkMessage::Type type)
00230 {
00231 int nbAttributes = diffusionList->size ;
00232
00233 FederateHandle toFederate ;
00234 for (int i = 0 ; i < nbAttributes ; i++) {
00235 toFederate = diffusionList->DiffArray[i].federate ;
00236 if (toFederate != 0) {
00237 std::auto_ptr<NetworkMessage> answer(NM_Factory::create(type));
00238 answer->federation = server->federation();
00239 answer->federate = theFederate ;
00240 answer->object = theObjectHandle ;
00241 answer->setLabel(theTag);
00242 answer->handleArray.resize(nbAttributes) ;
00243
00244 int index = 0 ;
00245 for (int j = i ; j < nbAttributes ; j++) {
00246 if (diffusionList->DiffArray[j].federate == toFederate) {
00247 D.Out(pdDebug, "handle : %u",
00248 diffusionList->DiffArray[j].attribute);
00249 diffusionList->DiffArray[j].federate = 0 ;
00250 answer->handleArray[index] = diffusionList
00251 ->DiffArray[j].attribute ;
00252 index++ ;
00253 }
00254 }
00255 answer->handleArraySize = index ;
00256 D.Out(pdDebug, "Envoi message type %u ", type);
00257 sendToFederate(answer.get(), toFederate);
00258 }
00259 }
00260 }
00261
00262
00266 void
00267 ObjectClass::checkFederateAccess(FederateHandle the_federate,
00268 const char *reason)
00269 throw (SecurityError)
00270 {
00271 D.Out(pdInit, "Beginning of CheckFederateAccess for the federate %d",
00272 the_federate);
00273
00274
00275 if (server == NULL)
00276 return ;
00277
00278 bool result = server->canFederateAccessData(the_federate, securityLevelId);
00279
00280
00281 if (!result) {
00282 cout << "Object Class " << handle << " : SecurityError for federate "
00283 << the_federate << '(' << reason << ")." << endl ;
00284 throw SecurityError("Federate should not access Object Class.");
00285 }
00286 }
00287
00288
00289 ObjectClass::ObjectClass(std::string name, ObjectClassHandle handle)
00290 : Named(name), server(NULL), handle(handle), maxSubscriberHandle(0), securityLevelId(PublicLevelID),
00291 superClass(0), subClasses(NULL)
00292 {
00293 subClasses = new ObjectClassSet(NULL);
00294 }
00295
00296
00298 ObjectClass::~ObjectClass()
00299 {
00300
00301 if (!objectSet.empty())
00302 D.Out(pdError,
00303 "ObjectClass %d : Instances remaining while exiting...", handle);
00304
00305
00306 while (!attributeSet.empty()) {
00307 delete attributeSet.front();
00308 attributeSet.pop_front();
00309 }
00310
00311 if (NULL!=subClasses) {
00312 delete subClasses;
00313 }
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 ObjectClassBroadcastList *
00325 ObjectClass::deleteInstance(FederateHandle the_federate,
00326 ObjectHandle the_object,
00327 FederationTime theTime,
00328 std::string the_tag)
00329 throw (DeletePrivilegeNotHeld,
00330 ObjectNotKnown,
00331 RTIinternalError)
00332 {
00333
00334
00335 Object *object = getInstanceWithID(the_object);
00336
00337
00338 if ((server != 0) && (object->getOwner() != the_federate)) {
00339 D.Out(pdExcept, "Delete Object %d: Federate %d not owner.",
00340 the_object, the_federate);
00341 throw DeletePrivilegeNotHeld("");
00342 }
00343
00344
00345 list<Object *>::iterator o ;
00346 for (o = objectSet.begin(); o != objectSet.end(); o++) {
00347 if ((*o)->getHandle() == the_object) {
00348 objectSet.erase(o);
00349 break ;
00350 }
00351 }
00352
00353
00354 ObjectClassBroadcastList *ocbList = NULL ;
00355 if (server != NULL) {
00356 D.Out(pdRegister,
00357 "Object %u deleted in class %u, now broadcasting...",
00358 the_object, handle);
00359
00360 NetworkMessage *answer = NM_Factory::create(NetworkMessage::REMOVE_OBJECT);
00361 answer->federation = server->federation();
00362 answer->federate = the_federate ;
00363 answer->exception = e_NO_EXCEPTION ;
00364 answer->objectClass = handle ;
00365 answer->object = the_object ;
00366
00367
00368 answer->setDate(theTime);
00369 answer->setLabel(the_tag);
00370
00371 ocbList = new ObjectClassBroadcastList(answer, 0);
00372 broadcastClassMessage(ocbList);
00373 }
00374 else {
00375 D.Out(pdRegister,
00376 "Object %u deleted in class %u, no broadcast to do.",
00377 the_object, handle);
00378 }
00379
00380
00381
00382 return ocbList ;
00383 }
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 ObjectClassBroadcastList *
00394 ObjectClass::deleteInstance(FederateHandle the_federate,
00395 ObjectHandle the_object,
00396 std::string the_tag)
00397 throw (DeletePrivilegeNotHeld,
00398 ObjectNotKnown,
00399 RTIinternalError)
00400 {
00401
00402 Object *object = getInstanceWithID(the_object);
00403
00404
00405 if ((server != 0) && (object->getOwner() != the_federate)) {
00406 D.Out(pdExcept, "Delete Object %d: Federate %d not owner.",
00407 the_object, the_federate);
00408 throw DeletePrivilegeNotHeld("");
00409 }
00410
00411
00412 list<Object *>::iterator o ;
00413 for (o = objectSet.begin(); o != objectSet.end(); o++) {
00414 if ((*o)->getHandle() == the_object) {
00415 objectSet.erase(o);
00416 break ;
00417 }
00418 }
00419
00420
00421 ObjectClassBroadcastList *ocbList = NULL ;
00422 if (server != NULL) {
00423 D.Out(pdRegister,
00424 "Object %u deleted in class %u, now broadcasting...",
00425 the_object, handle);
00426
00427 NetworkMessage *answer = NM_Factory::create(NetworkMessage::REMOVE_OBJECT);
00428 answer->federation = server->federation();
00429 answer->federate = the_federate ;
00430 answer->objectClass = handle ;
00431 answer->object = the_object ;
00432
00433
00434
00435 answer->setLabel(the_tag);
00436
00437 ocbList = new ObjectClassBroadcastList(answer, 0);
00438 broadcastClassMessage(ocbList);
00439 }
00440 else {
00441 D.Out(pdRegister,
00442 "Object %u deleted in class %u, no broadcast to do.",
00443 the_object, handle);
00444 }
00445
00446
00447
00448 return ocbList ;
00449 }
00450
00451
00453 void ObjectClass::display() const
00454 {
00455 cout << " ObjectClass #" << handle << " \"" << name << "\":" << endl ;
00456
00457
00458 cout << " Parent Class Handle: " << superClass << endl ;
00459 cout << " Security Level: " << securityLevelId << endl ;
00460 cout << " " << subClasses->size() << " Child(s):" << endl ;
00461 cout << " Subclasses handles:" ;
00462 ObjectClassSet::const_iterator i ;
00463 for (i = subClasses->begin(); i != subClasses->end(); ++i) {
00464 cout << " " << i->second->getHandle() << endl;
00465 }
00466
00467
00468
00469 cout << " " << attributeSet.size() << " Attribute(s):" << endl ;
00470 list<ObjectClassAttribute *>::const_iterator a ;
00471 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00472 (*a)->display();
00473 }
00474
00475
00476 cout << " " << objectSet.size() << " Instances(s):" << endl ;
00477 list<Object *>::const_iterator o ;
00478 for (o = objectSet.begin(); o != objectSet.end(); o++) {
00479 (*o)->display();
00480 }
00481 }
00482
00483
00485 AttributeHandle
00486 ObjectClass::getAttributeHandle(const char *the_name) const
00487 throw (NameNotFound, RTIinternalError)
00488 {
00489 G.Out(pdGendoc,"enter ObjectClass::getAttributeHandle");
00490
00491 list<ObjectClassAttribute *>::const_iterator a ;
00492 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00493 if ((*a)->isNamed(std::string(the_name))) {
00494 G.Out(pdGendoc,"exit ObjectClass::getAttributeHandle");
00495 return (*a)->getHandle();
00496 }
00497 }
00498
00499 D.Out(pdExcept, "ObjectClass %u: Attribute \"%s\" not defined.",
00500 handle, the_name);
00501 G.Out(pdGendoc,"exit ObjectClass::getAttributeHandle on NameNotFound");
00502 throw NameNotFound(the_name);
00503 }
00504
00505
00507 const char *
00508 ObjectClass::getAttributeName(AttributeHandle the_handle) const
00509 throw (AttributeNotDefined,
00510 RTIinternalError)
00511 {
00512 return getAttribute(the_handle)->getCName();
00513 }
00514
00515
00516
00521 ObjectClassAttribute *
00522 ObjectClass::getAttribute(AttributeHandle the_handle) const
00523 throw (AttributeNotDefined)
00524 {
00525 list<ObjectClassAttribute *>::const_iterator a ;
00526 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00527 if ((*a)->getHandle() == the_handle)
00528 return (*a);
00529 }
00530
00531 D.Out(pdExcept, "ObjectClass %d: Attribute %d not defined.",
00532 handle, the_handle);
00533
00534 throw AttributeNotDefined("");
00535 }
00536
00537
00539 Object *
00540 ObjectClass::getInstanceWithID(ObjectHandle the_id) const
00541 throw (ObjectNotKnown)
00542 {
00543 std::stringstream msg;
00544
00545 list<Object *>::const_iterator o ;
00546 for (o = objectSet.begin(); o != objectSet.end(); o++) {
00547 if ((*o)->getHandle() == the_id)
00548 return (*o);
00549 }
00550
00551 msg << "Could not find ObjectHandle <" << the_id << "> among <"
00552 << objectSet.size() << "> objects of ObjectClass "
00553 << handle;
00554
00555 D[pdError] << msg.str().c_str() << std::endl ;
00556
00557 throw ObjectNotKnown(msg.str().c_str());
00558 }
00559
00560
00562 bool
00563 ObjectClass::isFederatePublisher(FederateHandle the_federate) const
00564 {
00565 D.Out(pdRegister, "attributeSet.size() = %d.", attributeSet.size());
00566
00567 list<ObjectClassAttribute *>::const_iterator a ;
00568 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00569 if ((*a)->isPublishing(the_federate))
00570 return true ;
00571 }
00572 return false ;
00573 }
00574
00575
00581 bool
00582 ObjectClass::isSubscribed(FederateHandle fed) const
00583 {
00584 list<ObjectClassAttribute *>::const_iterator a ;
00585 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00586 if ((*a)->isSubscribed(fed))
00587 return true ;
00588 }
00589 return false ;
00590 }
00591
00592
00596 bool
00597 ObjectClass::isInstanceInClass(ObjectHandle theID)
00598 {
00599 try {
00600 getInstanceWithID(theID);
00601 }
00602 catch (ObjectNotKnown &e) {
00603 return false ;
00604 }
00605 return true ;
00606 }
00607
00608
00610 ObjectClassBroadcastList *
00611 ObjectClass::killFederate(FederateHandle the_federate)
00612 throw ()
00613 {
00614 D.Out(pdRegister, "Object Class %d: Killing Federate %d.",
00615 handle, the_federate);
00616 std::vector <AttributeHandle> liste_vide ;
00617 liste_vide.empty();
00618 try {
00619
00620 if (isFederatePublisher(the_federate)) {
00621 publish(the_federate, liste_vide, 0, false);
00622 }
00623
00624
00625
00626 if (isSubscribed(the_federate)) {
00627 unsubscribe(the_federate);
00628 }
00629 }
00630 catch (SecurityError &e) {}
00631
00632
00633 list<Object *>::iterator o ;
00634 for (o = objectSet.begin(); o != objectSet.end(); o++) {
00635 if ((*o)->getOwner() == the_federate) {
00636
00637
00638
00639
00640
00641
00642 return deleteInstance(the_federate, (*o)->getHandle(), "Killed");
00643 }
00644 }
00645
00646 D.Out(pdRegister, "Object Class %d:Federate %d killed.",
00647 handle, the_federate);
00648
00649
00650 return NULL ;
00651 }
00652
00653
00655 void
00656 ObjectClass::publish(FederateHandle theFederateHandle,
00657 std::vector <AttributeHandle> &theAttributeList,
00658 UShort theListSize,
00659 bool PubOrUnpub)
00660 throw (AttributeNotDefined,
00661 RTIinternalError,
00662 SecurityError)
00663 {
00664 D.Out(pdInit, "Beginning of Publish for the federate %d",
00665 theFederateHandle);
00666
00667
00668 for (UShort index = 0 ; index < theListSize ; index++)
00669 getAttribute(theAttributeList[index]);
00670
00671
00672 checkFederateAccess(theFederateHandle, "Publish");
00673
00674
00675 D.Out(pdInit, "ObjectClass %d: Reset publish info of Federate %d.",
00676 handle, theFederateHandle);
00677
00678 list<ObjectClassAttribute *>::const_iterator a ;
00679 for (a = attributeSet.begin(); a != attributeSet.end(); a++) {
00680 if ((*a)->isPublishing(theFederateHandle))
00681 (*a)->unpublish(theFederateHandle);
00682 }
00683
00684
00685 ObjectClassAttribute * attribute ;
00686 for (UShort i = 0 ; i < theListSize ; i++) {
00687 D.Out(pdInit, "ObjectClass %d: Federate %d publishes attribute %d.",
00688 handle, theFederateHandle, theAttributeList[i]);
00689 attribute = getAttribute(theAttributeList[i]);
00690 if (PubOrUnpub)
00691 attribute->publish(theFederateHandle);
00692 else
00693 attribute->unpublish(theFederateHandle);
00694 }
00695 }
00696
00697
00703 ObjectClassBroadcastList *
00704 ObjectClass::registerObjectInstance(FederateHandle the_federate,
00705 Object *the_object,
00706 ObjectClassHandle classHandle)
00707 throw (ObjectClassNotPublished,
00708 ObjectAlreadyRegistered,
00709 RTIinternalError)
00710 {
00711
00712 if (isInstanceInClass(the_object->getHandle())) {
00713 D.Out(pdExcept, "exception : ObjectAlreadyRegistered.");
00714 throw ObjectAlreadyRegistered(the_object->getName().c_str());
00715 }
00716
00717
00718 if ((server != NULL) && (!isFederatePublisher(the_federate))) {
00719 D.Out(pdExcept, "exception : ObjectClassNotPublished.");
00720 throw ObjectClassNotPublished("");
00721 }
00722
00723
00724
00725
00726 ObjectAttribute * oa ;
00727 list<ObjectClassAttribute *>::reverse_iterator a ;
00728 for (a = attributeSet.rbegin(); a != attributeSet.rend(); a++) {
00729 oa = new ObjectAttribute((*a)->getHandle(),
00730 (*a)->isPublishing(the_federate) ? the_federate : 0,
00731 *a);
00732
00733
00734 if ((*a)->isNamed("privilegeToDelete")) {
00735 oa->setOwner(the_federate);
00736 }
00737
00738 the_object->addAttribute(oa);
00739 }
00740
00741 objectSet.push_front(the_object);
00742 D[pdTrace] << "Added object " << the_object->getHandle() << "/"
00743 << objectSet.size() << " to class " << handle << std::endl ;
00744
00745
00746 ObjectClassBroadcastList *ocbList = NULL ;
00747 if (server != NULL) {
00748 D.Out(pdRegister,
00749 "Object %u registered in class %u, now broadcasting...",
00750 the_object->getHandle(), handle);
00751
00752 NM_Discover_Object *answer = new NM_Discover_Object();
00753 answer->federation = server->federation();
00754 answer->federate = the_federate ;
00755 answer->exception = e_NO_EXCEPTION ;
00756 answer->objectClass = handle ;
00757 answer->object = the_object->getHandle();
00758 answer->setLabel(the_object->getName().c_str());
00759
00760
00761
00762 ocbList = new ObjectClassBroadcastList(answer, 0);
00763 broadcastClassMessage(ocbList);
00764 }
00765 else {
00766 D.Out(pdRegister,
00767 "Object %u registered in class %u, no broadcast to do.",
00768 the_object->getHandle(), handle);
00769 }
00770
00771
00772
00773 return ocbList ;
00774 }
00775
00776
00786 bool
00787 ObjectClass::sendDiscoverMessages(FederateHandle federate,
00788 ObjectClassHandle super_handle)
00789 {
00790
00791 if ((handle != super_handle) && isSubscribed(federate))
00792 return false ;
00793
00794
00795 list<Object *>::const_iterator o ;
00796 for (o = objectSet.begin(); o != objectSet.end(); ++o) {
00797 if ((*o)->getOwner() != federate) {
00798 NM_Discover_Object message;
00799 D.Out(pdInit,
00800 "Sending DiscoverObj to Federate %d for Object %u in class %u ",
00801 federate, (*o)->getHandle(), handle, message.getLabel().c_str());
00802
00803 message.federation = server->federation();
00804 message.federate = federate ;
00805 message.exception = e_NO_EXCEPTION ;
00806 message.objectClass = super_handle ;
00807 message.object = (*o)->getHandle();
00808 message.setLabel((*o)->getName().c_str());
00809
00810
00811
00812 Socket *socket = NULL ;
00813 try {
00814 socket = server->getSocketLink(federate);
00815 message.send(socket,NM_msgBufSend);
00816 }
00817 catch (RTIinternalError &e) {
00818 D.Out(pdExcept,
00819 "Reference to a killed Federate while sending DO msg.");
00820 }
00821 catch (NetworkError &e) {
00822 D.Out(pdExcept, "Network error while sending DO msg, ignoring.");
00823 }
00824 }
00825 }
00826
00827 return true ;
00828 }
00829
00830
00831 void
00832 ObjectClass::setSecurityLevelId(SecurityLevelID new_levelID) throw (SecurityError)
00833 {
00834 if (!server->dominates(new_levelID, securityLevelId))
00835 throw SecurityError("Attempt to lower object class level.");
00836
00837 securityLevelId = new_levelID ;
00838 }
00839
00840
00850 bool
00851 ObjectClass::subscribe(FederateHandle fed,
00852 std::vector <AttributeHandle> &attributes,
00853 int nb_attributes,
00854 const RTIRegion *region)
00855 throw (AttributeNotDefined, RTIinternalError, SecurityError)
00856 {
00857 checkFederateAccess(fed, "Subscribe");
00858
00859 for (int i = 0 ; i < nb_attributes ; ++i)
00860 getAttribute(attributes[i]);
00861
00862 if (nb_attributes > 0)
00863 maxSubscriberHandle = std::max(fed, maxSubscriberHandle);
00864
00865 bool was_subscriber = isSubscribed(fed);
00866
00867
00868 unsubscribe(fed, region);
00869
00870 D[pdTrace] << "ObjectClass::subscribe" << " : fed " << fed << ", class " << handle
00871 << ", " << nb_attributes << " attributes, region "
00872 << (region ? region->getHandle() : 0) << std::endl ;
00873
00874 for (int i = 0 ; i < nb_attributes ; ++i) {
00875 getAttribute(attributes[i])->subscribe(fed, region);
00876 }
00877
00878 return (nb_attributes > 0) && !was_subscriber ;
00879 }
00880
00881
00883 ObjectClassBroadcastList *
00884 ObjectClass::updateAttributeValues(FederateHandle the_federate,
00885 Object *object,
00886 std::vector <AttributeHandle> &the_attributes,
00887 std::vector <AttributeValue_t> &the_values,
00888 int the_size,
00889 FederationTime the_time,
00890 const char *the_tag)
00891 throw (ObjectNotKnown,
00892 AttributeNotDefined,
00893 AttributeNotOwned,
00894 RTIinternalError,
00895 InvalidObjectHandle)
00896 {
00897
00898 ObjectAttribute * oa ;
00899 for (int i = 0 ; i < the_size ; i++) {
00900 oa = object->getAttribute(the_attributes[i]);
00901
00902 if (oa->getOwner() != the_federate)
00903 throw AttributeNotOwned("");
00904 }
00905
00906
00907 ObjectClassBroadcastList *ocbList = NULL ;
00908 if (server != NULL) {
00909 NetworkMessage *answer = NM_Factory::create(NetworkMessage::REFLECT_ATTRIBUTE_VALUES);
00910 answer->federation = server->federation();
00911 answer->federate = the_federate ;
00912 answer->exception = e_NO_EXCEPTION ;
00913 answer->object = object->getHandle();
00914
00915 answer->setDate(the_time);
00916 answer->setLabel(the_tag);
00917 answer->handleArray.resize(the_size) ;
00918 answer->handleArraySize = the_size ;
00919 answer->sizeValueArray(the_size) ;
00920
00921 for (int i = 0 ; i < the_size ; i++) {
00922 answer->handleArray[i] = the_attributes[i] ;
00923 answer->valueArray[i] = the_values[i] ;
00924 }
00925
00926 ocbList = new ObjectClassBroadcastList(answer, attributeSet.size());
00927
00928 D.Out(pdProtocol,
00929 "Object %u updated in class %u, now broadcasting...",
00930 object->getHandle(), handle);
00931
00932 broadcastClassMessage(ocbList, object);
00933 }
00934 else {
00935 D.Out(pdExcept,
00936 "UpdateAttributeValues should not be called on the RTIA.");
00937 throw RTIinternalError("UpdateAttributeValues called on the RTIA.");
00938 }
00939
00940
00941
00942 return ocbList ;
00943 }
00944
00945
00947 ObjectClassBroadcastList *
00948 ObjectClass::updateAttributeValues(FederateHandle the_federate,
00949 Object *object,
00950 std::vector <AttributeHandle> &the_attributes,
00951 std::vector <AttributeValue_t> &the_values,
00952 int the_size,
00953 const char *the_tag)
00954 throw (ObjectNotKnown,
00955 AttributeNotDefined,
00956 AttributeNotOwned,
00957 RTIinternalError,
00958 InvalidObjectHandle)
00959 {
00960
00961 ObjectAttribute * oa ;
00962 for (int i = 0 ; i < the_size ; i++) {
00963 oa = object->getAttribute(the_attributes[i]);
00964
00965 if (oa->getOwner() != the_federate)
00966 throw AttributeNotOwned("");
00967 }
00968
00969
00970 ObjectClassBroadcastList *ocbList = NULL ;
00971 if (server != NULL) {
00972 NetworkMessage *answer = NM_Factory::create(NetworkMessage::REFLECT_ATTRIBUTE_VALUES) ;
00973 answer->federation = server->federation();
00974 answer->federate = the_federate ;
00975 answer->exception = e_NO_EXCEPTION ;
00976 answer->object = object->getHandle();
00977
00978
00979 answer->setLabel(the_tag);
00980
00981 answer->handleArraySize = the_size ;
00982 answer->handleArray.resize(the_size) ;
00983 answer->sizeValueArray(the_size) ;
00984
00985 for (int i = 0 ; i < the_size ; i++) {
00986 answer->handleArray[i] = the_attributes[i] ;
00987 answer->valueArray[i] = the_values[i];
00988 }
00989
00990 ocbList = new ObjectClassBroadcastList(answer, attributeSet.size());
00991
00992 D.Out(pdProtocol,
00993 "Object %u updated in class %u, now broadcasting...",
00994 object->getHandle(), handle);
00995
00996 broadcastClassMessage(ocbList, object);
00997 }
00998 else {
00999 D.Out(pdExcept,
01000 "UpdateAttributeValues should not be called on the RTIA.");
01001 throw RTIinternalError("UpdateAttributeValues called on the RTIA.");
01002 }
01003
01004
01005
01006 return ocbList ;
01007 }
01008
01009
01011 ObjectClassBroadcastList * ObjectClass::
01012 negotiatedAttributeOwnershipDivestiture(FederateHandle theFederateHandle,
01013 ObjectHandle theObjectHandle,
01014 std::vector <AttributeHandle> &theAttributeList,
01015 UShort theListSize,
01016 const char *theTag)
01017 throw (ObjectNotKnown,
01018 AttributeNotDefined,
01019 AttributeNotOwned,
01020 AttributeAlreadyBeingDivested,
01021 RTIinternalError)
01022 {
01023
01024
01025
01026 Object *object = getInstanceWithID(theObjectHandle);
01027
01028
01029 for (int index = 0 ; index < theListSize ; index++)
01030 getAttribute(theAttributeList[index]);
01031
01032
01033
01034 D.Out(pdDebug, "NegotiatedDivestiture Demandeur : %u", theFederateHandle);
01035
01036 ObjectAttribute * oa ;
01037 ObjectClassAttribute * oca ;
01038 for (int i = 0 ; i < theListSize ; i++) {
01039 oca = getAttribute(theAttributeList[i]);
01040 oa = object->getAttribute(theAttributeList[i]);
01041
01042 D.Out(pdDebug, "Attribute Name : %s", oca->getName().c_str());
01043 D.Out(pdDebug, "Attribute Handle : %u", oa->getHandle());
01044 D.Out(pdDebug, "Attribute Owner : %u", oa->getOwner());
01045 if (oa->getOwner() != theFederateHandle)
01046 throw AttributeNotOwned("");
01047 if (oa->beingDivested())
01048 throw AttributeAlreadyBeingDivested("");
01049 }
01050
01051 int compteur_acquisition = 0 ;
01052 int compteur_assumption = 0 ;
01053 int compteur_divestiture = 0 ;
01054 ObjectClassBroadcastList *List = NULL ;
01055 FederateHandle NewOwner ;
01056
01057 if (server != NULL) {
01058 NetworkMessage *AnswerAssumption = NM_Factory::create(NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION) ;
01059 NM_Attribute_Ownership_Divestiture_Notification AnswerDivestiture;
01060
01061 AnswerAssumption->handleArraySize = theListSize ;
01062 AnswerAssumption->handleArray.resize(theListSize) ;
01063
01064
01065 AnswerDivestiture.handleArray.resize(theListSize) ;
01066
01067 CDiffusion diffusionAcquisition;
01068
01069 ObjectAttribute * oa ;
01070 ObjectClassAttribute * oca ;
01071 for (int i = 0 ; i < theListSize ; i++) {
01072 oa = object->getAttribute(theAttributeList[i]);
01073
01074 if (oa->hasCandidates()) {
01075
01076
01077
01078
01079 NewOwner = oa->getCandidate(1);
01080
01081 oa->setOwner(NewOwner);
01082
01083
01084 oa->removeCandidate(NewOwner);
01085
01086
01087 oa->setDivesting(false);
01088
01089 diffusionAcquisition.DiffArray[compteur_acquisition]
01090 .federate = NewOwner ;
01091 diffusionAcquisition.DiffArray[compteur_acquisition]
01092 .attribute = oa->getHandle();
01093 compteur_acquisition++ ;
01094
01095 AnswerDivestiture.handleArray[compteur_divestiture]
01096 = theAttributeList[i] ;
01097 compteur_divestiture++ ;
01098
01099 if (oca->isNamed("privilegeToDelete")) {
01100 object->setOwner(NewOwner);
01101 }
01102 }
01103 else {
01104 AnswerAssumption->handleArray[compteur_assumption]
01105 = theAttributeList[i] ;
01106 oa->setDivesting(true);
01107 compteur_assumption++ ;
01108 }
01109 }
01110
01111 if (compteur_acquisition != 0) {
01112 diffusionAcquisition.size = compteur_acquisition ;
01113 sendToOwners(&diffusionAcquisition, theObjectHandle,
01114 theFederateHandle, theTag,
01115 NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION);
01116 }
01117
01118 if (compteur_divestiture !=0) {
01119 AnswerDivestiture.federation = server->federation();
01120 AnswerDivestiture.federate = theFederateHandle ;
01121 AnswerDivestiture.object = theObjectHandle ;
01122 AnswerDivestiture.setLabel(std::string(""));
01123 AnswerDivestiture.handleArraySize = compteur_divestiture ;
01124
01125 sendToFederate(&AnswerDivestiture, theFederateHandle);
01126 }
01127
01128 if (compteur_assumption !=0) {
01129 AnswerAssumption->federation = server->federation();
01130 AnswerAssumption->federate = theFederateHandle ;
01131 AnswerAssumption->exception = e_NO_EXCEPTION ;
01132 AnswerAssumption->object = theObjectHandle ;
01133 AnswerAssumption->setLabel(theTag);
01134 AnswerAssumption->handleArraySize = compteur_assumption ;
01135
01136 List = new ObjectClassBroadcastList(AnswerAssumption,
01137 attributeSet.size());
01138
01139 D.Out(pdProtocol,
01140 "Object %u divestiture in class %u, now broadcasting...",
01141 theObjectHandle, handle);
01142 broadcastClassMessage(List);
01143 }
01144 else
01145 delete AnswerAssumption ;
01146 }
01147 else {
01148 D.Out(pdExcept,
01149 "NegotiatedAttributeOwnershipDivestiture should not "
01150 "be called on the RTIA.");
01151 throw RTIinternalError("NegotiatedAttributeOwnershipDivestiture "
01152 "called on the RTIA.");
01153 }
01154
01155
01156
01157 return List ;
01158 }
01159
01160
01162 void ObjectClass::
01163 attributeOwnershipAcquisitionIfAvailable(FederateHandle the_federate,
01164 ObjectHandle the_object,
01165 std::vector <AttributeHandle> &the_attributes,
01166 UShort theListSize)
01167 throw (ObjectNotKnown,
01168 ObjectClassNotPublished,
01169 AttributeNotDefined,
01170 AttributeNotPublished,
01171 FederateOwnsAttributes,
01172 AttributeAlreadyBeingAcquired,
01173 RTIinternalError)
01174 {
01175
01176 Object *object = getInstanceWithID(the_object);
01177
01178
01179 for (int index = 0 ; index < theListSize ; index++) {
01180 getAttribute(the_attributes[index]);
01181 }
01182
01183 if (server) {
01184
01185 if (!isFederatePublisher(the_federate)) {
01186 D.Out(pdExcept, "exception : ObjectClassNotPublished.");
01187 throw ObjectClassNotPublished("");
01188 }
01189
01190
01191 ObjectAttribute * oa ;
01192 ObjectClassAttribute * oca ;
01193 for (int i = 0 ; i < theListSize ; i++) {
01194 oca = getAttribute(the_attributes[i]);
01195 oa = object->getAttribute(the_attributes[i]);
01196
01197
01198
01199 if (!oca->isPublishing(the_federate) &&
01200 (!oca->isNamed("privilegeToDelete")))
01201 throw AttributeNotPublished("");
01202
01203 if (oa->getOwner() == the_federate)
01204 throw FederateOwnsAttributes("");
01205
01206 if (oa->isCandidate(the_federate))
01207 throw AttributeAlreadyBeingAcquired("");
01208 }
01209
01210 NetworkMessage *Answer_notification = NM_Factory::create(NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION);
01211 Answer_notification->federation = server->federation();
01212 Answer_notification->federate = the_federate ;
01213 Answer_notification->exception = e_NO_EXCEPTION ;
01214 Answer_notification->object = the_object ;
01215 Answer_notification->handleArray.resize(theListSize) ;
01216
01217 NetworkMessage *Answer_unavailable = NM_Factory::create(NetworkMessage::ATTRIBUTE_OWNERSHIP_UNAVAILABLE) ;
01218 Answer_unavailable->federation = server->federation();
01219 Answer_unavailable->federate = the_federate ;
01220 Answer_unavailable->exception = e_NO_EXCEPTION ;
01221 Answer_unavailable->object = the_object ;
01222 Answer_unavailable->handleArray.resize(theListSize) ;
01223
01224 CDiffusion *diffusionDivestiture = new CDiffusion();
01225
01226
01227
01228
01229
01230 int compteur_unavailable = 0 ;
01231 int compteur_notification = 0 ;
01232 int compteur_divestiture = 0 ;
01233 FederateHandle oldOwner ;
01234
01235 for (int i = 0 ; i < theListSize ; i++) {
01236 oca = getAttribute(the_attributes[i]);
01237 oa = object->getAttribute(the_attributes[i]);
01238
01239 oldOwner = oa->getOwner();
01240 if ((oldOwner == 0) || (oa->beingDivested())) {
01241
01242
01243 if (oa->beingDivested()) {
01244 diffusionDivestiture->DiffArray[compteur_divestiture].federate
01245 = oldOwner ;
01246 diffusionDivestiture->DiffArray[compteur_divestiture].attribute
01247 = oa->getHandle();
01248 compteur_divestiture++ ;
01249 }
01250
01251 Answer_notification->handleArray[compteur_notification]
01252 = the_attributes[i] ;
01253 oa->setOwner(the_federate);
01254 oa->setDivesting(false);
01255 compteur_notification++ ;
01256
01257
01258 if (oca->isNamed("privilegeToDelete"))
01259 object->setOwner(the_federate);
01260 }
01261 else {
01262
01263 Answer_unavailable->handleArray[compteur_unavailable]
01264 = the_attributes[i] ;
01265 oa->addCandidate(the_federate);
01266 compteur_unavailable++ ;
01267 }
01268 }
01269
01270 if (compteur_notification != 0) {
01271 Answer_notification->handleArraySize = compteur_notification ;
01272 sendToFederate(Answer_notification, the_federate);
01273 }
01274 else
01275 delete Answer_notification ;
01276
01277 D.Out(pdDebug,
01278 "Debut traitement : send divestiture notification message");
01279
01280 if (compteur_divestiture != 0) {
01281 diffusionDivestiture->size =compteur_divestiture ;
01282 sendToOwners(diffusionDivestiture, the_object,
01283 the_federate, "\0",
01284 NetworkMessage::ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION);
01285 }
01286 delete diffusionDivestiture ;
01287
01288 if (compteur_unavailable != 0) {
01289 Answer_unavailable->handleArraySize = compteur_unavailable ;
01290 sendToFederate(Answer_unavailable, the_federate);
01291 }
01292 else
01293 delete Answer_unavailable ;
01294 }
01295 else {
01296 D.Out(pdExcept, "AttributeOwnershipAcquisitionIfAvailable should not "
01297 "be called on the RTIA.");
01298 throw RTIinternalError("AttributeOwnershipAcquisitionIfAvailable "
01299 "called on the RTIA.");
01300 }
01301 }
01302
01303
01305 ObjectClassBroadcastList * ObjectClass::
01306 unconditionalAttributeOwnershipDivestiture(FederateHandle theFederateHandle,
01307 ObjectHandle theObjectHandle,
01308 std::vector <AttributeHandle> &theAttributeList,
01309 UShort theListSize)
01310 throw (ObjectNotKnown,
01311 AttributeNotDefined,
01312 AttributeNotOwned,
01313 RTIinternalError)
01314 {
01315
01316
01317
01318 Object *object = getInstanceWithID(theObjectHandle);
01319
01320
01321 for (int index = 0 ; index < theListSize ; index++)
01322 getAttribute(theAttributeList[index]);
01323
01324
01325 ObjectAttribute * oa ;
01326 for (int i = 0 ; i < theListSize ; i++) {
01327 oa = object->getAttribute(theAttributeList[i]);
01328
01329 if (oa->getOwner() != theFederateHandle)
01330 throw AttributeNotOwned("");
01331 }
01332
01333 int compteur_assumption = 0 ;
01334 int compteur_acquisition = 0 ;
01335 NM_Request_Attribute_Ownership_Assumption *AnswerAssumption = NULL ;
01336 ObjectClassBroadcastList *List = NULL ;
01337 FederateHandle NewOwner ;
01338
01339 if (server != NULL) {
01340 AnswerAssumption = new NM_Request_Attribute_Ownership_Assumption();
01341 AnswerAssumption->handleArraySize = theListSize ;
01342 AnswerAssumption->handleArray.resize(theListSize) ;
01343 CDiffusion *diffusionAcquisition = new CDiffusion();
01344
01345 ObjectAttribute * oa ;
01346 ObjectClassAttribute * oca ;
01347 for (int i = 0 ; i < theListSize ; i++) {
01348 oca = getAttribute(theAttributeList[i]);
01349 oa = object->getAttribute(theAttributeList[i]);
01350
01351 if (oa->hasCandidates()) {
01352
01353
01354
01355
01356 NewOwner = oa->getCandidate(1);
01357
01358 oa->setOwner(NewOwner);
01359
01360
01361 oa->removeCandidate(NewOwner);
01362
01363
01364 oa->setDivesting(false);
01365
01366 diffusionAcquisition->DiffArray[compteur_acquisition]
01367 .federate = NewOwner ;
01368 diffusionAcquisition->DiffArray[compteur_acquisition]
01369 .attribute = oa->getHandle();
01370 compteur_acquisition++ ;
01371
01372 if (oca->isNamed("privilegeToDelete")) {
01373 object->setOwner(NewOwner);
01374 }
01375 }
01376 else {
01377 AnswerAssumption->handleArray[compteur_assumption] =
01378 theAttributeList[i] ;
01379 oa->setOwner(0);
01380 oa->setDivesting(false);
01381 compteur_assumption++ ;
01382 }
01383 }
01384
01385 if (compteur_assumption != 0) {
01386 AnswerAssumption->federation = server->federation();
01387 AnswerAssumption->federate = theFederateHandle ;
01388 AnswerAssumption->exception = e_NO_EXCEPTION ;
01389 AnswerAssumption->object = theObjectHandle ;
01390 AnswerAssumption->setLabel(std::string(""));
01391 AnswerAssumption->handleArraySize = compteur_assumption ;
01392
01393 List = new ObjectClassBroadcastList(AnswerAssumption,
01394 attributeSet.size());
01395
01396 D.Out(pdProtocol,
01397 "Object %u updated in class %u, now broadcasting...",
01398 theObjectHandle, handle);
01399
01400 broadcastClassMessage(List);
01401 }
01402 else
01403 delete AnswerAssumption ;
01404
01405 if (compteur_acquisition != 0) {
01406 diffusionAcquisition->size =compteur_acquisition ;
01407 sendToOwners(diffusionAcquisition, theObjectHandle,
01408 theFederateHandle, "\0",
01409 NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION);
01410 }
01411 delete diffusionAcquisition ;
01412 }
01413 else {
01414 D.Out(pdExcept, "UnconditionalAttributeOwnershipDivestiture should "
01415 "not be called on the RTIA.");
01416 throw RTIinternalError("UnconditionalAttributeOwnershipDivestiture "
01417 "called on the RTIA.");
01418 }
01419
01420
01421
01422 return List ;
01423 }
01424
01425
01427 void
01428 ObjectClass::attributeOwnershipAcquisition(FederateHandle theFederateHandle,
01429 ObjectHandle theObjectHandle,
01430 std::vector <AttributeHandle> &theAttributeList,
01431 UShort theListSize,
01432 const char *theTag)
01433 throw (ObjectNotKnown,
01434 ObjectClassNotPublished,
01435 AttributeNotDefined,
01436 AttributeNotPublished,
01437 FederateOwnsAttributes,
01438 RTIinternalError)
01439 {
01440
01441
01442
01443
01444
01445
01446 Object *object = getInstanceWithID(theObjectHandle);
01447
01448 ObjectAttribute * oa ;
01449 ObjectClassAttribute * oca ;
01450 for (int i = 0 ; i < theListSize ; i++) {
01451
01452 oca = getAttribute(theAttributeList[i]);
01453 oa = object->getAttribute(theAttributeList[i]);
01454
01455
01456 if (oa->getOwner() == theFederateHandle)
01457 throw FederateOwnsAttributes("");
01458
01459 if (!oca->isPublishing(theFederateHandle) &&
01460 (!oca->isNamed("privilegeToDelete")))
01461 throw AttributeNotPublished("");
01462 }
01463
01464 int compteur_notification = 0 ;
01465 int compteur_divestiture = 0 ;
01466 int compteur_release = 0 ;
01467 FederateHandle oldOwner ;
01468 if (server != NULL) {
01469
01470 if (!isFederatePublisher(theFederateHandle)) {
01471 D.Out(pdExcept, "exception : ObjectClassNotPublished.");
01472 throw ObjectClassNotPublished("");
01473 }
01474
01475 NetworkMessage *AnswerNotification = NM_Factory::create(NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION);
01476
01477 AnswerNotification->federation = server->federation();
01478 AnswerNotification->federate = theFederateHandle ;
01479 AnswerNotification->exception = e_NO_EXCEPTION ;
01480 AnswerNotification->object = theObjectHandle ;
01481 AnswerNotification->handleArray.resize(theListSize) ;
01482
01483 CDiffusion *diffusionDivestiture = new CDiffusion();
01484
01485 CDiffusion *diffusionRelease = new CDiffusion();
01486
01487 ObjectAttribute * oa ;
01488 ObjectClassAttribute * oca ;
01489 for (int i = 0 ; i < theListSize ; i++) {
01490 oca = getAttribute(theAttributeList[i]);
01491 oa = object->getAttribute(theAttributeList[i]);
01492
01493 oldOwner = oa->getOwner();
01494 if ((oldOwner == 0) || (oa->beingDivested())) {
01495
01496 if (oa->beingDivested()) {
01497 diffusionDivestiture->DiffArray[compteur_divestiture].federate =
01498 oldOwner ;
01499 diffusionDivestiture->DiffArray[compteur_divestiture].attribute =
01500 oa->getHandle();
01501 compteur_divestiture++ ;
01502 }
01503
01504 if (oa->isCandidate(theFederateHandle) != 0)
01505 oa->removeCandidate(theFederateHandle);
01506 AnswerNotification->handleArray[compteur_notification]
01507 = theAttributeList[i] ;
01508 oa->setOwner(theFederateHandle);
01509 oa->setDivesting(false);
01510 compteur_notification++ ;
01511
01512
01513
01514 if (oca->isNamed("privilegeToDelete"))
01515 object->setOwner(theFederateHandle);
01516 }
01517 else {
01518 diffusionRelease->DiffArray[compteur_release].federate = oldOwner ;
01519 diffusionRelease->DiffArray[compteur_release].attribute =
01520 oa->getHandle();
01521 compteur_release++ ;
01522
01523
01524 oa->removeCandidate(theFederateHandle);
01525
01526
01527 oa->addCandidate(theFederateHandle);
01528 }
01529 }
01530
01531 if (compteur_notification != 0) {
01532 AnswerNotification->handleArraySize = compteur_notification ;
01533 sendToFederate(AnswerNotification, theFederateHandle);
01534 }
01535 else
01536 delete AnswerNotification ;
01537
01538 if (compteur_divestiture != 0) {
01539 diffusionDivestiture->size =compteur_divestiture ;
01540 sendToOwners(diffusionDivestiture, theObjectHandle,
01541 theFederateHandle, "\0",
01542 NetworkMessage::ATTRIBUTE_OWNERSHIP_DIVESTITURE_NOTIFICATION);
01543 }
01544 delete diffusionDivestiture ;
01545
01546 if (compteur_release != 0) {
01547 diffusionRelease->size =compteur_release ;
01548 sendToOwners(diffusionRelease, theObjectHandle, theFederateHandle,
01549 theTag, NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_RELEASE);
01550 }
01551 delete diffusionRelease ;
01552 }
01553 else {
01554 D.Out(pdExcept,
01555 "AttributeOwnershipAcquisition should not be called "
01556 "on the RTIA.");
01557 throw RTIinternalError("AttributeOwnershipAcquisition called "
01558 "on the RTIA");
01559 }
01560 }
01561
01562
01564 AttributeHandleSet *
01565 ObjectClass::
01566 attributeOwnershipReleaseResponse(FederateHandle the_federate,
01567 ObjectHandle the_object,
01568 std::vector <AttributeHandle> &the_attributes,
01569 UShort the_size)
01570 throw (ObjectNotKnown,
01571 AttributeNotDefined,
01572 AttributeNotOwned,
01573 FederateWasNotAskedToReleaseAttribute,
01574 RTIinternalError)
01575 {
01576
01577
01578
01579 Object *object = getInstanceWithID(the_object);
01580
01581
01582 for (int index = 0 ; index < the_size ; index++) {
01583 getAttribute(the_attributes[index]);
01584 }
01585
01586
01587
01588 ObjectAttribute * oa ;
01589 for (int i = 0 ; i < the_size ; i++) {
01590 oa = object->getAttribute(the_attributes[i]);
01591
01592 if (oa->getOwner() != the_federate) {
01593 throw AttributeNotOwned("");
01594 }
01595 if (!oa->hasCandidates()) {
01596 throw FederateWasNotAskedToReleaseAttribute("");
01597 }
01598 }
01599
01600 int compteur_acquisition = 0 ;
01601 FederateHandle newOwner ;
01602 AttributeHandleSet *theAttribute ;
01603 if (server != NULL) {
01604 CDiffusion *diffusionAcquisition = new CDiffusion();
01605
01606 theAttribute = new AttributeHandleSet(the_size);
01607
01608 ObjectClassAttribute * oca ;
01609 for (int i = 0 ; i < the_size ; i++) {
01610 oca = getAttribute(the_attributes[i]);
01611 oa = object->getAttribute(the_attributes[i]);
01612
01613
01614 newOwner = oa->getCandidate(1);
01615
01616 oa->setOwner(newOwner);
01617
01618
01619 oa->removeCandidate(newOwner);
01620
01621
01622 oa->setDivesting(false);
01623
01624 diffusionAcquisition->DiffArray[compteur_acquisition].federate = newOwner ;
01625 diffusionAcquisition->DiffArray[compteur_acquisition].attribute =
01626 oa->getHandle();
01627 compteur_acquisition++ ;
01628 theAttribute->add(oa->getHandle());
01629
01630 D.Out(pdDebug, "Acquisition handle %u compteur %u",
01631 the_attributes[i], compteur_acquisition);
01632
01633 if (oca->isNamed("privilegeToDelete"))
01634 object->setOwner(newOwner);
01635 }
01636
01637 if (compteur_acquisition != 0) {
01638 diffusionAcquisition->size =compteur_acquisition ;
01639 sendToOwners(diffusionAcquisition, the_object, the_federate, "\0",
01640 NetworkMessage::ATTRIBUTE_OWNERSHIP_ACQUISITION_NOTIFICATION);
01641 }
01642 delete diffusionAcquisition ;
01643 }
01644 else {
01645 D.Out(pdExcept, "NegotiatedAttributeOwnershipDivestiture should not "
01646 "be called on the RTIA.");
01647 throw RTIinternalError("NegotiatedAttributeOwnershipDivestiture called"
01648 " on the RTIA.");
01649 }
01650
01651 return(theAttribute);
01652 }
01653
01654
01656 void
01657 ObjectClass::
01658 cancelAttributeOwnershipAcquisition(FederateHandle federate_handle,
01659 ObjectHandle object_handle,
01660 std::vector <AttributeHandle> &attribute_list,
01661 UShort list_size)
01662 throw (ObjectNotKnown,
01663 AttributeNotDefined,
01664 AttributeAlreadyOwned,
01665 AttributeAcquisitionWasNotRequested,
01666 RTIinternalError)
01667 {
01668
01669
01670
01671 Object *object = getInstanceWithID(object_handle);
01672
01673
01674 for (int index = 0 ; index < list_size ; index++)
01675 getAttribute(attribute_list[index]);
01676
01677 for (int i = 0 ; i < list_size ; i++)
01678 D.Out(pdDebug, "CancelAcquisition Object %u Attribute %u ",
01679 object_handle, attribute_list[i]);
01680
01681 if (server != NULL) {
01682
01683 ObjectAttribute * oa ;
01684 ObjectClassAttribute * oca ;
01685
01686 for (int i = 0 ; i < list_size ; i++) {
01687 oca = getAttribute(attribute_list[i]);
01688 oa = object->getAttribute(attribute_list[i]);
01689
01690 D.Out(pdDebug, "Attribut %u Owner %u", attribute_list[i], oa->getOwner());
01691
01692 if (oa->getOwner() == federate_handle)
01693 throw AttributeAlreadyOwned("");
01694
01695 if (oa->isCandidate(federate_handle) == 0)
01696 throw AttributeAcquisitionWasNotRequested("");
01697 }
01698
01699 NetworkMessage *answer_confirmation = NM_Factory::create(NetworkMessage::CONFIRM_ATTRIBUTE_OWNERSHIP_ACQUISITION_CANCELLATION);
01700 answer_confirmation->federation = server->federation();
01701 answer_confirmation->federate = federate_handle ;
01702 answer_confirmation->exception = e_NO_EXCEPTION ;
01703 answer_confirmation->object = object_handle ;
01704 answer_confirmation->handleArray.resize(list_size) ;
01705
01706 int compteur_confirmation = 0 ;
01707 for (int i = 0 ; i < list_size ; i++) {
01708 oa = object->getAttribute(attribute_list[i]);
01709
01710 answer_confirmation->handleArray[compteur_confirmation] = attribute_list[i] ;
01711
01712
01713 oa->removeCandidate(federate_handle);
01714 D.Out(pdDebug, "Adding federate %u to attribute %u object %u",
01715 federate_handle, attribute_list[i], object_handle);
01716 compteur_confirmation++ ;
01717 }
01718
01719 if (compteur_confirmation != 0) {
01720 answer_confirmation->handleArraySize = compteur_confirmation ;
01721 sendToFederate(answer_confirmation, federate_handle);
01722 }
01723 else
01724 delete answer_confirmation ;
01725 }
01726 else {
01727 D.Out(pdExcept, "CancelAttributeOwnershipAcquisition should not "
01728 "be called on the RTIA.");
01729 throw RTIinternalError("CancelAttributeOwnershipAcquisition called "
01730 "on the RTIA.");
01731 }
01732 }
01733
01734
01735 ObjectClassHandle
01736 ObjectClass::getHandle() const
01737 {
01738 return handle ;
01739 }
01740
01741
01744 void
01745 ObjectClass::unsubscribe(FederateHandle fed, const RTIRegion *region)
01746 {
01747 D[pdTrace] << "ObjectClass::unsubscribe" << ": fed " << fed << ", region "
01748 << (region ? region->getHandle() : 0) << std::endl ;
01749
01750 list<ObjectClassAttribute *>::iterator i ;
01751 for (i = attributeSet.begin(); i != attributeSet.end(); ++i) {
01752 if ((*i)->isSubscribed(fed, region)) {
01753 (*i)->unsubscribe(fed, region);
01754 }
01755 }
01756 }
01757
01758
01761 void
01762 ObjectClass::unsubscribe(FederateHandle fed)
01763 {
01764 list<ObjectClassAttribute *>::iterator i ;
01765 for (i = attributeSet.begin(); i != attributeSet.end(); ++i) {
01766 if ((*i)->isSubscribed(fed)) {
01767 (*i)->unsubscribe(fed);
01768 }
01769 }
01770 }
01771
01772 void
01773 ObjectClass::addSubClass(ObjectClass *child) {
01774
01775
01776
01777 subClasses->addClass(child,NULL);
01778
01779 child->superClass = handle;
01780
01781
01782 addInheritedClassAttributes(child);
01783
01784 child->server = server;
01785
01786 child->setSecurityLevelId(securityLevelId);
01787
01788 }
01789
01790
01795 void
01796 ObjectClass::recursiveDiscovering(FederateHandle federate,
01797 ObjectClassHandle subscription)
01798 throw (ObjectClassNotDefined)
01799 {
01800 D[pdInit] << "Recursive Discovering on class " << handle
01801 << " for Federate " << federate << "." << std::endl ;
01802
01803 bool go_deeper = sendDiscoverMessages(federate, subscription);
01804
01805 if (go_deeper) {
01806 ObjectClassSet::const_iterator i ;
01807 for (i = subClasses->begin(); i != subClasses->end(); ++i) {
01808 i->second->recursiveDiscovering(federate, subscription);
01809 }
01810 }
01811 }
01812
01813
01818
01819
01820
01821
01822
01823
01824
01825
01826
01827
01828
01829
01830
01831 ObjectClass::AttributeList_t
01832 ObjectClass::getAttributeList(void) {
01833 return attributeSet;
01834 }
01835
01836 }
01837
01838