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 #include <assert.h>
00027
00028 #include "ObjectClassBroadcastList.hh"
00029 #include "PrettyDebug.hh"
00030 #include "NM_Classes.hh"
00031
00032 using std::list ;
00033
00034 namespace certi {
00035
00036 static pdCDebug D("BROADCAST", __FILE__);
00037 static PrettyDebug G("GENDOC",__FILE__);
00038
00039
00042 ObjectBroadcastLine::ObjectBroadcastLine(FederateHandle theFederate,
00043 ObjectBroadcastLine::State init_state)
00044 {
00045 Federate = theFederate ;
00046 for (AttributeHandle i = 0 ; i <= MAX_STATE_SIZE ; i++)
00047 state[i] = init_state ;
00048 }
00049
00050
00051
00052
00057 NetworkMessage *
00058 ObjectClassBroadcastList::adaptMessage(ObjectBroadcastLine *line)
00059 {
00060 G.Out(pdGendoc,"enter ObjectClassBroadcastList::adaptMessage");
00061 G.Out(pdGendoc," message->objectClass=%d",message->objectClass);
00062
00063 if ((message->getType() != NetworkMessage::REFLECT_ATTRIBUTE_VALUES) &&
00064 (message->getType() != NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION))
00065 throw RTIinternalError("Bad Message type in Broadcast's AdaptMsg.");
00066
00067
00068 NetworkMessage *reducedMessage = NM_Factory::create(message->getType());
00069 reducedMessage->exception = message->exception ;
00070 reducedMessage->federation = message->federation ;
00071 reducedMessage->federate = message->federate ;
00072 reducedMessage->object = message->object ;
00073 if (message->isDated()) {
00074 reducedMessage->setDate(message->getDate());
00075 }
00076 if (message->isTagged()) {
00077 reducedMessage->setTag(message->getTag());
00078 }
00079 reducedMessage->objectClass = message->objectClass ;
00080
00081 if (message->isLabelled()) {
00082 reducedMessage->setLabel(message->getLabel());
00083 }
00084
00085 UShort currentSize ;
00086 AttributeHandle currentAttrib ;
00087
00088 reducedMessage->handleArraySize = 0 ;
00089
00090 for (UShort i = 0 ; i < message->handleArraySize ; i++) {
00091
00092 currentAttrib = message->handleArray[i] ;
00093
00094 if (line->state[currentAttrib] == ObjectBroadcastLine::waiting) {
00095
00096
00097 currentSize = reducedMessage->handleArraySize ;
00098 reducedMessage->handleArraySize ++ ;
00099 reducedMessage->handleArray.resize(reducedMessage->handleArraySize);
00100 reducedMessage->sizeValueArray(reducedMessage->handleArraySize);
00101
00102
00103 reducedMessage->handleArray[currentSize] = currentAttrib ;
00104
00105 if (message->getType() == NetworkMessage::REFLECT_ATTRIBUTE_VALUES) {
00106
00107 reducedMessage->valueArray[currentSize] = message->valueArray[i];
00108 }
00109 }
00110 }
00111 G.Out(pdGendoc," reducedMessage->objectClass=%d",reducedMessage->objectClass);
00112 G.Out(pdGendoc,"exit ObjectClassBroadcastList::adaptMessage");
00113 return reducedMessage ;
00114 }
00115
00116
00124 void
00125 ObjectClassBroadcastList::addFederate(FederateHandle theFederate,
00126 AttributeHandle theAttribute)
00127 {
00128 if (theAttribute > maxHandle) {
00129 D.Out(pdExcept, "Bad attribute handle: %u > %u.", theAttribute,
00130 maxHandle);
00131 throw RTIinternalError("");
00132 }
00133
00134 ObjectBroadcastLine *line = getLineWithFederate(theFederate);
00135
00136 if (line == 0) {
00137 line =
00138 new ObjectBroadcastLine(theFederate, ObjectBroadcastLine::notSub);
00139 lines.push_front(line);
00140 D.Out(pdRegister, "Adding new line in list for Federate %d.",
00141 theFederate);
00142 }
00143
00144 if (line->state[theAttribute] != ObjectBroadcastLine::sent) {
00145 line->state[theAttribute] = ObjectBroadcastLine::waiting ;
00146 D.Out(pdRegister, "List attribute %d for Federate %d is now "
00147 "ObjectBroadcastLine::waiting.", theAttribute, theFederate);
00148 }
00149 else
00150 D.Out(pdTrace,
00151 "Message already sent to federate %d about attribute %d.",
00152 theFederate, theAttribute);
00153 }
00154
00155
00162 ObjectClassBroadcastList::ObjectClassBroadcastList(NetworkMessage *theMsg,
00163 AttributeHandle maxAttHandle)
00164 : maxHandle(maxAttHandle)
00165 {
00166 ObjectBroadcastLine *firstLine = 0 ;
00167
00168 if (theMsg == 0)
00169 throw RTIinternalError("Null Broadcast Message.");
00170
00171 message = theMsg ;
00172
00173
00174 if (message->federate != 0) {
00175 firstLine = new ObjectBroadcastLine(message->federate,
00176 ObjectBroadcastLine::sent);
00177 lines.push_front(firstLine);
00178 }
00179 }
00180
00181
00183 ObjectClassBroadcastList::~ObjectClassBroadcastList()
00184 {
00185 this->clear();
00186 }
00187
00188
00190 void
00191 ObjectClassBroadcastList::clear()
00192 {
00193 delete message ;
00194 message = 0 ;
00195
00196 maxHandle = 0 ;
00197
00198 while (!lines.empty()) {
00199 delete lines.front();
00200 lines.pop_front();
00201 }
00202
00203 D.Out(pdTerm, "List is now empty.");
00204 }
00205
00206
00207
00208 ObjectBroadcastLine*
00209 ObjectClassBroadcastList::getLineWithFederate(FederateHandle theFederate)
00210 {
00211 list<ObjectBroadcastLine *>::iterator i ;
00212 for (i = lines.begin(); i != lines.end(); i++) {
00213 if ((*i)->Federate == theFederate)
00214 return (*i);
00215 }
00216
00217 return 0 ;
00218 }
00219
00220
00224 bool
00225 ObjectClassBroadcastList::isWaiting(ObjectBroadcastLine *line)
00226 {
00227 for (unsigned int attrIndex = 1 ; attrIndex <= maxHandle ; attrIndex++) {
00228 if (line->state[attrIndex] == ObjectBroadcastLine::waiting) {
00229 return true ;
00230 }
00231 }
00232
00233 return false ;
00234 }
00235
00236
00237
00238
00239
00240
00241 void
00242 ObjectClassBroadcastList::sendPendingDOMessage(SecurityServer *server)
00243 {
00244 Socket *socket = NULL ;
00245
00246
00247 list<ObjectBroadcastLine *>::iterator i ;
00248 for (i = lines.begin(); i != lines.end(); ++i) {
00249
00250 if ((*i)->state[0] == ObjectBroadcastLine::waiting) {
00251
00252
00253 D.Out(pdProtocol,
00254 "Broadcasting message to Federate %d.", (*i)->Federate);
00255 try {
00256 socket = server->getSocketLink((*i)->Federate);
00257
00258 if ( socket != NULL )
00259 message->send(socket,NM_msgBufSend);
00260 }
00261 catch (RTIinternalError &e) {
00262 D.Out(pdExcept,
00263 "Reference to a killed Federate while broadcasting.");
00264 }
00265 catch (NetworkError &e) {
00266 D.Out(pdExcept, "Network error while broadcasting, ignoring.");
00267 }
00268
00269
00270 (*i)->state[0] = ObjectBroadcastLine::sent ;
00271 }
00272 else
00273 D.Out(pdProtocol, "No message sent to Federate %d.",
00274 (*i)->Federate);
00275 }
00276 }
00277
00278
00291 void ObjectClassBroadcastList::sendPendingMessage(SecurityServer *server)
00292 {
00293 G.Out(pdGendoc,"enter ObjectClassBroadcastList::sendPendingMessage");
00294 switch (message->getType()) {
00295
00296 case NetworkMessage::REFLECT_ATTRIBUTE_VALUES:
00297 case NetworkMessage::REQUEST_ATTRIBUTE_OWNERSHIP_ASSUMPTION:
00298 sendPendingRAVMessage(server);
00299 break ;
00300
00301 case NetworkMessage::DISCOVER_OBJECT:
00302 case NetworkMessage::REMOVE_OBJECT:
00303 sendPendingDOMessage(server);
00304 break ;
00305
00306 default:
00307 throw RTIinternalError("Unknown message type to broadcast.");
00308 G.Out(pdGendoc,"exit ObjectClassBroadcastList::sendPendingMessage");
00309 }
00310 }
00311
00312
00313
00314
00315
00316 void
00317 ObjectClassBroadcastList::sendPendingRAVMessage(SecurityServer *server)
00318 {
00319 Socket *socket = 0 ;
00320 NetworkMessage *currentMessage = 0 ;
00321
00322 G.Out(pdGendoc,"enter ObjectClassBroadcastList::sendPendingRAVMessage");
00323
00324 list<ObjectBroadcastLine *>::iterator i ;
00325 for (i = lines.begin(); i != lines.end(); i++) {
00326
00327
00328 if (isWaiting(*i)) {
00329
00330
00331
00332 bool all_waiting = true ;
00333 for (unsigned int attrIndex = 0 ;
00334 attrIndex < message->handleArraySize ;
00335 attrIndex ++) {
00336 AttributeHandle attrib = message->handleArray[attrIndex] ;
00337 if ((*i)->state[attrib] != ObjectBroadcastLine::waiting)
00338 all_waiting = false ;
00339 }
00340
00341 if (!all_waiting) {
00342
00343
00344 currentMessage = adaptMessage(*i);
00345 D.Out(pdProtocol,
00346 "Broadcasting reduced message to Federate %d.",
00347 (*i)->Federate);
00348 }
00349 else {
00350
00351 currentMessage = message ;
00352 D.Out(pdProtocol,
00353 "Broadcasting complete message to Federate %d.",
00354 (*i)->Federate);
00355 }
00356
00357
00358 try {
00359 #ifdef HLA_USES_UDP
00360 socket = server->getSocketLink((*i)->Federate, BEST_EFFORT);
00361 #else
00362 socket = server->getSocketLink((*i)->Federate);
00363 #endif
00364
00365 if ( socket != NULL )
00366 {
00367 G.Out(pdGendoc," sendPendingRAVMessage=====> write");
00368 currentMessage->send(socket,NM_msgBufSend);
00369 }
00370 }
00371 catch (RTIinternalError &e) {
00372 D.Out(pdExcept,
00373 "Reference to a killed Federate while broadcasting.");
00374 }
00375 catch (NetworkError &e) {
00376 D.Out(pdExcept, "Network error while broadcasting, ignoring.");
00377 }
00378
00379
00380 for (unsigned int attrIndex = 1 ;
00381 attrIndex <= maxHandle ;
00382 attrIndex ++) {
00383 if ((*i)->state[attrIndex] == ObjectBroadcastLine::waiting) {
00384 (*i)->state[attrIndex] = ObjectBroadcastLine::sent ;
00385 }
00386 }
00387
00388
00389 if (currentMessage != message) {
00390 delete currentMessage ;
00391 currentMessage = NULL ;
00392 }
00393
00394 }
00395 else
00396 D.Out(pdProtocol, "No message sent to Federate %d.",
00397 (*i)->Federate);
00398 G.Out(pdGendoc,"exit ObjectClassBroadcastList::sendPendingRAVMessage");
00399 }
00400 }
00401
00402 }
00403
00404