00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00024 #include <IPAddressResolver.h>
00025 #include <NotificationBoard.h>
00026 #include <UDPAppBase.h>
00027 #include <UDPSocket.h>
00028 #include <cassert>
00029
00030 #include <CommonMessages_m.h>
00031 #include <BaseRpc.h>
00032 #include <OverlayAccess.h>
00033 #include <GlobalNodeListAccess.h>
00034 #include <GlobalStatisticsAccess.h>
00035 #include <UnderlayConfiguratorAccess.h>
00036
00037 #include "BaseApp.h"
00038
00039 using namespace std;
00040
00041 BaseApp::BaseApp()
00042 {
00043 notificationBoard = NULL;
00044
00045 overlay = NULL;
00046 }
00047
00048 BaseApp::~BaseApp()
00049 {
00050 finishRpcs();
00051 }
00052
00053 int BaseApp::numInitStages() const
00054 {
00055 return MAX_STAGE_APP + 1;
00056 }
00057
00058 void BaseApp::initialize(int stage)
00059 {
00060 CompType compType = getThisCompType();
00061 bool tier = (compType == TIER1_COMP ||
00062 compType == TIER2_COMP ||
00063 compType == TIER3_COMP);
00064
00065 if (stage == REGISTER_STAGE) {
00066 OverlayAccess().get(this)->registerComp(getThisCompType(), this);
00067 return;
00068 }
00069
00070 if ((tier && stage == MIN_STAGE_APP) ||
00071 (!tier && stage == MIN_STAGE_COMPONENTS)) {
00072
00073 debugOutput = par("debugOutput");
00074
00075 globalNodeList = GlobalNodeListAccess().get();
00076 underlayConfigurator = UnderlayConfiguratorAccess().get();
00077 globalStatistics = GlobalStatisticsAccess().get();
00078 notificationBoard = NotificationBoardAccess().get();
00079
00080
00081 notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00082 notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE);
00083 notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00084
00085
00086 if (getParentModule()->getSubmodule("interfaceTable", 0) != NULL) {
00087 thisNode.setAddress(IPAddressResolver()
00088 .addressOf(getParentModule()));
00089 } else {
00090 thisNode.setAddress(IPAddressResolver()
00091 .addressOf(getParentModule()->getParentModule()));
00092 }
00093
00094 thisNode.setPort(-1);
00095
00096 WATCH(thisNode);
00097
00098
00099 numOverlaySent = 0;
00100 numOverlayReceived = 0;
00101 bytesOverlaySent = 0;
00102 bytesOverlayReceived = 0;
00103 numUdpSent = 0;
00104 numUdpReceived = 0;
00105 bytesUdpSent = 0;
00106 bytesUdpReceived = 0;
00107
00108 creationTime = simTime();
00109
00110 WATCH(numOverlaySent);
00111 WATCH(numOverlayReceived);
00112 WATCH(bytesOverlaySent);
00113 WATCH(bytesOverlayReceived);
00114 WATCH(numUdpSent);
00115 WATCH(numUdpReceived);
00116 WATCH(bytesUdpSent);
00117 WATCH(bytesUdpReceived);
00118
00119
00120 initRpcs();
00121 }
00122
00123 if ((stage >= MIN_STAGE_APP && stage <= MAX_STAGE_APP) ||
00124 (stage >= MIN_STAGE_COMPONENTS && stage <= MAX_STAGE_COMPONENTS))
00125 initializeApp(stage);
00126 }
00127
00128 void BaseApp::initializeApp(int stage)
00129 {
00130
00131 }
00132
00133
00134 void BaseApp::handleMessage(cMessage* msg)
00135 {
00136 if (internalHandleMessage(msg)) {
00137 return;
00138 }
00139
00140 if (msg->arrivedOn("from_lowerTier") ||
00141 msg->arrivedOn("direct_in")) {
00142 CompReadyMessage* readyMsg = dynamic_cast<CompReadyMessage*>(msg);
00143 if (readyMsg != NULL) {
00144 handleReadyMessage(readyMsg);
00145 return;
00146 }
00147
00148 CommonAPIMessage* commonAPIMsg = dynamic_cast<CommonAPIMessage*>(msg);
00149 if (commonAPIMsg != NULL) {
00150 handleCommonAPIMessage(commonAPIMsg);
00151 } else if (msg->arrivedOn("from_lowerTier")) {
00152
00153 cPacket* packet = check_and_cast<cPacket*>(msg);
00154 RECORD_STATS(numOverlayReceived++;
00155 bytesOverlayReceived += packet->getByteLength());
00156 handleLowerMessage(msg);
00157 }
00158 else delete msg;
00159 } else if (msg->arrivedOn("from_upperTier")) {
00160 handleUpperMessage(msg);
00161 } else if (msg->arrivedOn("udpIn")) {
00162 cPacket* packet = check_and_cast<cPacket*>(msg);
00163 RECORD_STATS(numUdpReceived++; bytesUdpReceived += packet->getByteLength());
00164
00165 if (debugOutput && !ev.isDisabled()) {
00166 UDPControlInfo* udpControlInfo =
00167 check_and_cast<UDPControlInfo*>(msg->getControlInfo());
00168 EV << "[BaseApp:handleMessage() @ " << thisNode.getAddress()
00169 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00170 << " Received " << *msg << " from "
00171 << udpControlInfo->getSrcAddr() << endl;
00172 }
00173 handleUDPMessage(msg);
00174 } else if (msg->arrivedOn("trace_in")) {
00175 handleTraceMessage(msg);
00176 } else {
00177 delete msg;
00178 }
00179 }
00180
00181 CompType BaseApp::getThisCompType()
00182 {
00183 std::string name(this->getName());
00184
00185 if (name == std::string("tier1")) {
00186 return TIER1_COMP;
00187 } else if (name == std::string("tier2")) {
00188 return TIER2_COMP;
00189 } else if (name == std::string("tier3")) {
00190 return TIER3_COMP;
00191 }
00192
00193 std::string parentName(this->getParentModule()->getName());
00194
00195 if (parentName == std::string("tier1")) {
00196 return TIER1_COMP;
00197 } else if (parentName == std::string("tier2")) {
00198 return TIER2_COMP;
00199 } else if (parentName == std::string("tier3")) {
00200 return TIER3_COMP;
00201 } else {
00202 throw cRuntimeError("BaseApp::getThisCompType(): "
00203 "Unknown module type!");
00204 }
00205
00206 return INVALID_COMP;
00207 }
00208
00209 void BaseApp::receiveChangeNotification(int category, const cPolymorphic * details)
00210 {
00211 Enter_Method_Silent();
00212 if (category == NF_OVERLAY_TRANSPORTADDRESS_CHANGED) {
00213 handleTransportAddressChangedNotification();
00214 } else if (category == NF_OVERLAY_NODE_LEAVE) {
00215 handleNodeLeaveNotification();
00216 } else if (category == NF_OVERLAY_NODE_GRACEFUL_LEAVE) {
00217 handleNodeGracefulLeaveNotification();
00218 }
00219 }
00220
00221 void BaseApp::handleTransportAddressChangedNotification()
00222 {
00223
00224 }
00225
00226 void BaseApp::handleNodeLeaveNotification()
00227 {
00228
00229 }
00230
00231 void BaseApp::handleNodeGracefulLeaveNotification()
00232 {
00233
00234 }
00235
00236 void BaseApp::callRoute(const OverlayKey& key, cPacket* msg,
00237 const std::vector<TransportAddress>& sourceRoute,
00238 RoutingType routingType)
00239 {
00240
00241 KBRroute* routeMsg = new KBRroute();
00242 routeMsg->setDestKey(key);
00243
00244 if (!(sourceRoute.size() == 1 && sourceRoute[0].isUnspecified())) {
00245 routeMsg->setSourceRouteArraySize(sourceRoute.size());
00246 for (uint32_t i = 0; i < sourceRoute.size(); ++i) {
00247 routeMsg->setSourceRoute(i, sourceRoute[i]);
00248 }
00249 }
00250 routeMsg->encapsulate(msg);
00251 routeMsg->setSrcComp(thisCompType);
00252 routeMsg->setDestComp(thisCompType);
00253 routeMsg->setRoutingType(routingType);
00254
00255 routeMsg->setType(KBR_ROUTE);
00256
00257 sendDirect(routeMsg, overlay->getCompRpcGate(OVERLAY_COMP));
00258
00259
00260 if (debugOutput && !ev.isDisabled()) {
00261 EV << "[BaseApp::callRoute() @ " << thisNode.getAddress()
00262 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00263 << " Sending " << *msg
00264 << " to destination key " << key
00265 << " with source route ";
00266
00267 for (uint32_t i = 0; i < sourceRoute.size(); ++i) {
00268 EV << sourceRoute[i] << " ";
00269 }
00270
00271 EV << endl;
00272 }
00273
00274
00275 RECORD_STATS(numOverlaySent++; bytesOverlaySent += msg->getByteLength());
00276 }
00277
00278 void BaseApp::deliver(OverlayKey& key, cMessage* msg)
00279 {
00280
00281
00282 delete msg;
00283 }
00284
00285 void BaseApp::forward(OverlayKey* key, cPacket** msg, NodeHandle* nextHopNode)
00286 {
00287
00288 }
00289
00290 void BaseApp::forwardResponse(const OverlayKey& key, cPacket* msg,
00291 const NodeHandle& nextHopNode)
00292 {
00293 OverlayCtrlInfo* ctrlInfo =
00294 check_and_cast<OverlayCtrlInfo*>(msg->removeControlInfo());
00295
00296
00297 KBRforward* forwardMsg = new KBRforward();
00298 forwardMsg->setDestKey(key);
00299 forwardMsg->setNextHopNode(nextHopNode);
00300 forwardMsg->setControlInfo(ctrlInfo);
00301 forwardMsg->encapsulate(msg);
00302
00303 forwardMsg->setType(KBR_FORWARD_RESPONSE);
00304
00305 if (getThisCompType() == TIER1_COMP) {
00306 send(forwardMsg, "to_lowerTier");
00307 } else {
00308 sendDirect(forwardMsg, overlay->getCompRpcGate(OVERLAY_COMP));
00309 }
00310 }
00311
00312 void BaseApp::update(const NodeHandle& node, bool joined)
00313 {
00314 }
00315
00316 void BaseApp::handleCommonAPIMessage(CommonAPIMessage* commonAPIMsg)
00317 {
00318 cPacket* tempMsg = commonAPIMsg->decapsulate();
00319
00320
00321 OverlayCtrlInfo* overlayCtrlInfo =
00322 dynamic_cast<OverlayCtrlInfo*>(commonAPIMsg->removeControlInfo());
00323
00324 if (overlayCtrlInfo != NULL) {
00325 tempMsg->setControlInfo(overlayCtrlInfo);
00326 }
00327
00328 switch (commonAPIMsg->getType()) {
00329 case KBR_DELIVER:
00330 {
00331 KBRdeliver* apiMsg = dynamic_cast<KBRdeliver*>(commonAPIMsg);
00332 OverlayKey key = apiMsg->getDestKey();
00333 NodeHandle nextHopNode = overlay->getThisNode();
00334
00335
00336 forward(&key, &tempMsg, &nextHopNode);
00337
00338 if(tempMsg != NULL) {
00339
00340 if ((!key.isUnspecified() && key != apiMsg->getDestKey()) ||
00341 (!nextHopNode.isUnspecified()
00342 && nextHopNode != overlay->getThisNode())) {
00343 forwardResponse(key, tempMsg, nextHopNode);
00344 }
00345 else {
00346 RECORD_STATS(numOverlayReceived++;
00347 bytesOverlayReceived += tempMsg->getByteLength());
00348
00349 assert(overlayCtrlInfo->getTransportType()
00350 == ROUTE_TRANSPORT);
00351
00352
00353 if (debugOutput) {
00354 EV << "[BaseApp:handleCommonAPIMessage() @ "
00355 << thisNode.getAddress() << " ("
00356 << overlay->getThisNode().getKey().toString(16) << ")]\n"
00357 << " Received " << *tempMsg << " from "
00358 << overlayCtrlInfo->getSrcRoute() << endl;
00359 }
00360
00361
00362 BaseRpcMessage* rpcMessage
00363 = dynamic_cast<BaseRpcMessage*>(tempMsg);
00364 if (rpcMessage!=NULL) {
00365 internalHandleRpcMessage(rpcMessage);
00366 } else {
00367 deliver(apiMsg->getDestKey(), tempMsg);
00368 }
00369 }
00370 }
00371 break;
00372 }
00373
00374 case KBR_FORWARD:
00375 {
00376 KBRforward* apiMsg = dynamic_cast<KBRforward*>(commonAPIMsg);
00377 OverlayKey key = apiMsg->getDestKey();
00378 NodeHandle nextHopNode = apiMsg->getNextHopNode();
00379
00380 forward(&key, &tempMsg, &nextHopNode);
00381
00382
00383 if(tempMsg != NULL) {
00384 if(nextHopNode == apiMsg->getNextHopNode())
00385
00386 nextHopNode = NodeHandle::UNSPECIFIED_NODE;
00387 forwardResponse(key, tempMsg, nextHopNode);
00388 }
00389 break;
00390 }
00391
00392 case KBR_UPDATE:
00393 {
00394 KBRupdate* apiMsg = dynamic_cast<KBRupdate*>(commonAPIMsg);
00395 update(apiMsg->getNode(), apiMsg->getJoined());
00396
00397 break;
00398 }
00399
00400 default:
00401 {
00402 delete tempMsg;
00403 }
00404 }
00405 delete commonAPIMsg;
00406 }
00407
00408 void BaseApp::handleUpperMessage(cMessage* msg)
00409 {
00410 delete msg;
00411 }
00412
00413 void BaseApp::handleLowerMessage(cMessage* msg)
00414 {
00415 delete msg;
00416 }
00417
00418 void BaseApp::handleUDPMessage(cMessage *msg)
00419 {
00420 delete msg;
00421 }
00422
00423 void BaseApp::handleReadyMessage(CompReadyMessage* msg)
00424 {
00425 delete msg;
00426 }
00427
00428 void BaseApp::handleTraceMessage(cMessage* msg)
00429 {
00430 throw cRuntimeError("This application cannot handle trace data. "
00431 "You have to overwrite handleTraceMessage() in your "
00432 "application to make trace files work");
00433 }
00434
00435 void BaseApp::sendMessageToLowerTier(cPacket* msg)
00436 {
00437 RECORD_STATS(numOverlaySent++; bytesOverlaySent += msg->getByteLength());
00438
00439 send(msg, "to_lowerTier");
00440 }
00441 void BaseApp::sendReadyMessage(bool ready)
00442 {
00443 CompReadyMessage* msg = new CompReadyMessage();
00444 msg->setReady(ready);
00445 msg->setComp(getThisCompType());
00446
00447 overlay->sendMessageToAllComp(msg, getThisCompType());
00448 }
00449
00450 void BaseApp::finish()
00451 {
00452
00453 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00454
00455 string baseAppName = string("BaseApp (") += string(this->getName())
00456 += string("): ");
00457
00458 if (time >= GlobalStatistics::MIN_MEASURED) {
00459 globalStatistics->addStdDev(baseAppName + string("Sent Messages/s to "
00460 "Overlay"),
00461 numOverlaySent / time);
00462 globalStatistics->addStdDev(baseAppName +
00463 string("Received Messages/s from Overlay"),
00464 numOverlayReceived / time);
00465 globalStatistics->addStdDev(baseAppName + string("Sent Bytes/s to "
00466 "Overlay"),
00467 bytesOverlaySent / time);
00468 globalStatistics->addStdDev(baseAppName + string("Received Bytes/s "
00469 "from Overlay"),
00470 bytesOverlayReceived / time);
00471 globalStatistics->addStdDev(baseAppName + string("Sent Messages/s to "
00472 "UDP"),
00473 numUdpSent / time);
00474 globalStatistics->addStdDev(baseAppName +
00475 string("Received Messages/s from UDP"),
00476 numUdpReceived / time);
00477 globalStatistics->addStdDev(baseAppName + string("Sent Bytes/s to UDP"),
00478 bytesUdpSent / time);
00479 globalStatistics->addStdDev(baseAppName + string("Received Bytes/s "
00480 "from UDP"),
00481 bytesUdpReceived / time);
00482
00483 }
00484
00485 finishApp();
00486 }
00487
00488 void BaseApp::finishApp()
00489 {
00490
00491 }
00492
00493 void BaseApp::bindToPort(int port)
00494 {
00495 EV << "[BaseApp::bindToPort() @ " << thisNode.getAddress()
00496 << ": Binding to UDP port " << port << endl;
00497
00498 thisNode.setPort(port);
00499
00500 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00501 UDPControlInfo *ctrl = new UDPControlInfo();
00502 ctrl->setSrcPort(port);
00503 ctrl->setSockId(UDPSocket::generateSocketId());
00504 msg->setControlInfo(ctrl);
00505 send(msg, "udpOut");
00506 }
00507
00508 void BaseApp::sendMessageToUDP(const TransportAddress& destAddr, cPacket *msg)
00509 {
00510
00511 msg->removeControlInfo();
00512 msg->setKind(UDP_C_DATA);
00513
00514 UDPControlInfo *ctrl = new UDPControlInfo();
00515 ctrl->setSrcPort(thisNode.getPort());
00516 ctrl->setSrcAddr(thisNode.getAddress());
00517 ctrl->setDestAddr(destAddr.getAddress());
00518 ctrl->setDestPort(destAddr.getPort());
00519 msg->setControlInfo(ctrl);
00520
00521 if (ev.isGUI()) {
00522 BaseRpcMessage* rpc = dynamic_cast<BaseRpcMessage*>(msg);
00523 if (rpc) rpc->setStatType(APP_DATA_STAT);
00524 }
00525
00526
00527 if (debugOutput) {
00528 EV << "[BaseApp::sendMessageToUDP() @ " << thisNode.getAddress()
00529 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00530 << " Sending " << *msg << " to " << destAddr.getAddress()
00531 << endl;
00532 }
00533
00534
00535 RECORD_STATS(numUdpSent++; bytesUdpSent += msg->getByteLength());
00536 send(msg, "udpOut");
00537 }
00538
00539
00540 bool BaseApp::internalHandleRpcCall(BaseCallMessage* msg)
00541 {
00542
00543 return BaseRpc::internalHandleRpcCall(msg);
00544 }
00545
00546 void BaseApp::internalHandleRpcResponse(BaseResponseMessage* msg,
00547 cPolymorphic* context,
00548 int rpcId, simtime_t rtt)
00549 {
00550
00551 BaseRpc::internalHandleRpcResponse(msg, context, rpcId, rtt);
00552 }
00553
00554 void BaseApp::internalSendRouteRpc(BaseRpcMessage* message,
00555 const OverlayKey& destKey,
00556 const std::vector<TransportAddress>&
00557 sourceRoute,
00558 RoutingType routingType) {
00559 callRoute(destKey, message, sourceRoute, routingType);
00560 }
00561
00562 void BaseApp::internalSendRpcResponse(BaseCallMessage* call,
00563 BaseResponseMessage* response)
00564 {
00565
00566 TransportType transportType = UDP_TRANSPORT;
00567 CompType compType = INVALID_COMP;
00568 const TransportAddress* destNode = &TransportAddress::UNSPECIFIED_NODE;
00569 const OverlayKey* destKey = &OverlayKey::UNSPECIFIED_KEY;
00570
00571 TransportAddress tempNode;
00572
00573 OverlayCtrlInfo* overlayCtrlInfo =
00574 dynamic_cast<OverlayCtrlInfo*>(call->getControlInfo());
00575
00576 if (overlayCtrlInfo &&
00577 overlayCtrlInfo->getTransportType() == ROUTE_TRANSPORT) {
00578
00579 if (overlayCtrlInfo->getSrcNode().isUnspecified())
00580 destNode = &(overlayCtrlInfo->getLastHop());
00581 else
00582 destNode = &(overlayCtrlInfo->getSrcNode());
00583 transportType = ROUTE_TRANSPORT;
00584 compType = static_cast<CompType>(overlayCtrlInfo->getSrcComp());
00585 if (static_cast<RoutingType>(overlayCtrlInfo->getRoutingType())
00586 == FULL_RECURSIVE_ROUTING) {
00587 destKey = &(overlayCtrlInfo->getSrcNode().getKey());
00588 destNode = &NodeHandle::UNSPECIFIED_NODE;
00589 }
00590 } else {
00591 UDPControlInfo* udpCtrlInfo =
00592 check_and_cast<UDPControlInfo*>(call->getControlInfo());
00593
00594 tempNode = TransportAddress(udpCtrlInfo->getSrcAddr(), udpCtrlInfo->getSrcPort());
00595 destNode = &tempNode;
00596
00597 }
00598
00599 sendRpcResponse(transportType, compType,
00600 *destNode, *destKey, call, response);
00601 }