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 <GlobalNodeListAccess.h>
00033 #include <GlobalStatisticsAccess.h>
00034 #include <UnderlayConfiguratorAccess.h>
00035
00036 #include "BaseApp.h"
00037
00038 using namespace std;
00039
00040 BaseApp::BaseApp()
00041 {
00042 notificationBoard = NULL;
00043
00044 overlay = NULL;
00045 }
00046
00047 BaseApp::~BaseApp()
00048 {
00049 finishRpcs();
00050 }
00051
00052 int BaseApp::numInitStages() const
00053 {
00054 return MAX_STAGE_APP + 1;
00055 }
00056
00057 void BaseApp::initialize(int stage)
00058 {
00059 CompType compType = getThisCompType();
00060 bool tier = (compType == TIER1_COMP ||
00061 compType == TIER2_COMP ||
00062 compType == TIER3_COMP);
00063
00064 if ((tier && stage == MIN_STAGE_APP) ||
00065 (!tier && stage == MIN_STAGE_COMPONENTS)) {
00066
00067 debugOutput = par("debugOutput");
00068
00069 globalNodeList = GlobalNodeListAccess().get();
00070 underlayConfigurator = UnderlayConfiguratorAccess().get();
00071 globalStatistics = GlobalStatisticsAccess().get();
00072 notificationBoard = NotificationBoardAccess().get();
00073
00074
00075 notificationBoard->subscribe(this, NF_OVERLAY_TRANSPORTADDRESS_CHANGED);
00076 notificationBoard->subscribe(this, NF_OVERLAY_NODE_LEAVE);
00077 notificationBoard->subscribe(this, NF_OVERLAY_NODE_GRACEFUL_LEAVE);
00078
00079
00080 if (getParentModule()->getSubmodule("interfaceTable", 0) != NULL) {
00081 thisNode.setAddress(IPAddressResolver()
00082 .addressOf(getParentModule()).get4());
00083 } else {
00084 thisNode.setAddress(IPAddressResolver()
00085 .addressOf(getParentModule()->getParentModule()).get4());
00086 }
00087
00088 thisNode.setPort(-1);
00089
00090 WATCH(thisNode);
00091
00092
00093 numOverlaySent = 0;
00094 numOverlayReceived = 0;
00095 bytesOverlaySent = 0;
00096 bytesOverlayReceived = 0;
00097 numUdpSent = 0;
00098 numUdpReceived = 0;
00099 bytesUdpSent = 0;
00100 bytesUdpReceived = 0;
00101
00102 creationTime = simTime();
00103
00104 WATCH(numOverlaySent);
00105 WATCH(numOverlayReceived);
00106 WATCH(bytesOverlaySent);
00107 WATCH(bytesOverlayReceived);
00108 WATCH(numUdpSent);
00109 WATCH(numUdpReceived);
00110 WATCH(bytesUdpSent);
00111 WATCH(bytesUdpReceived);
00112
00113
00114 initRpcs();
00115 }
00116
00117 if ((stage >= MIN_STAGE_APP && stage <= MAX_STAGE_APP) ||
00118 (stage >= MIN_STAGE_COMPONENTS && stage <= MAX_STAGE_COMPONENTS))
00119 initializeApp(stage);
00120 }
00121
00122 void BaseApp::initializeApp(int stage)
00123 {
00124
00125 }
00126
00127
00128 void BaseApp::handleMessage(cMessage* msg)
00129 {
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 if (internalHandleMessage(msg)) return;
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
00442 void BaseApp::finish()
00443 {
00444
00445 simtime_t time = globalStatistics->calcMeasuredLifetime(creationTime);
00446
00447 string baseAppName = string("BaseApp (") += string(this->getName())
00448 += string("): ");
00449
00450 if (time >= GlobalStatistics::MIN_MEASURED) {
00451 globalStatistics->addStdDev(baseAppName + string("Sent Messages/s to "
00452 "Overlay"),
00453 numOverlaySent / time);
00454 globalStatistics->addStdDev(baseAppName +
00455 string("Received Messages/s from Overlay"),
00456 numOverlayReceived / time);
00457 globalStatistics->addStdDev(baseAppName + string("Sent Bytes/s to "
00458 "Overlay"),
00459 bytesOverlaySent / time);
00460 globalStatistics->addStdDev(baseAppName + string("Received Bytes/s "
00461 "from Overlay"),
00462 bytesOverlayReceived / time);
00463 globalStatistics->addStdDev(baseAppName + string("Sent Messages/s to "
00464 "UDP"),
00465 numUdpSent / time);
00466 globalStatistics->addStdDev(baseAppName +
00467 string("Received Messages/s from UDP"),
00468 numUdpReceived / time);
00469 globalStatistics->addStdDev(baseAppName + string("Sent Bytes/s to UDP"),
00470 bytesUdpSent / time);
00471 globalStatistics->addStdDev(baseAppName + string("Received Bytes/s "
00472 "from UDP"),
00473 bytesUdpReceived / time);
00474
00475 }
00476
00477 finishApp();
00478 }
00479
00480 void BaseApp::finishApp()
00481 {
00482
00483 }
00484
00485 void BaseApp::bindToPort(int port)
00486 {
00487 EV << "[BaseApp::bindToPort() @ " << thisNode.getAddress()
00488 << ": Binding to UDP port " << port << endl;
00489
00490 thisNode.setPort(port);
00491
00492 cMessage *msg = new cMessage("UDP_C_BIND", UDP_C_BIND);
00493 UDPControlInfo *ctrl = new UDPControlInfo();
00494 ctrl->setSrcPort(port);
00495 ctrl->setSockId(UDPSocket::generateSocketId());
00496 msg->setControlInfo(ctrl);
00497 send(msg, "udpOut");
00498 }
00499
00500 void BaseApp::sendMessageToUDP(const TransportAddress& destAddr, cPacket *msg)
00501 {
00502
00503 msg->removeControlInfo();
00504 msg->setKind(UDP_C_DATA);
00505
00506 UDPControlInfo *ctrl = new UDPControlInfo();
00507 ctrl->setSrcPort(thisNode.getPort());
00508 ctrl->setSrcAddr(thisNode.getAddress());
00509 ctrl->setDestAddr(destAddr.getAddress());
00510 ctrl->setDestPort(destAddr.getPort());
00511 msg->setControlInfo(ctrl);
00512
00513 if (ev.isGUI()) {
00514 BaseRpcMessage* rpc = dynamic_cast<BaseRpcMessage*>(msg);
00515 if (rpc) rpc->setStatType(APP_DATA_STAT);
00516 }
00517
00518
00519 if (debugOutput) {
00520 EV << "[BaseApp::sendMessageToUDP() @ " << thisNode.getAddress()
00521 << " (" << overlay->getThisNode().getKey().toString(16) << ")]\n"
00522 << " Sending " << *msg << " to " << destAddr.getAddress()
00523 << endl;
00524 }
00525
00526
00527 RECORD_STATS(numUdpSent++; bytesUdpSent += msg->getByteLength());
00528 send(msg, "udpOut");
00529 }
00530
00531
00532 bool BaseApp::internalHandleRpcCall(BaseCallMessage* msg)
00533 {
00534
00535 return BaseRpc::internalHandleRpcCall(msg);
00536 }
00537
00538 void BaseApp::internalHandleRpcResponse(BaseResponseMessage* msg,
00539 cPolymorphic* context,
00540 int rpcId, simtime_t rtt)
00541 {
00542
00543 BaseRpc::internalHandleRpcResponse(msg, context, rpcId, rtt);
00544 }
00545
00546 void BaseApp::internalSendRouteRpc(BaseRpcMessage* message,
00547 const OverlayKey& destKey,
00548 const std::vector<TransportAddress>&
00549 sourceRoute,
00550 RoutingType routingType) {
00551 callRoute(destKey, message, sourceRoute, routingType);
00552 }
00553
00554 void BaseApp::internalSendRpcResponse(BaseCallMessage* call,
00555 BaseResponseMessage* response)
00556 {
00557
00558 TransportType transportType = UDP_TRANSPORT;
00559 CompType compType = INVALID_COMP;
00560 const TransportAddress* destNode = &TransportAddress::UNSPECIFIED_NODE;
00561 const OverlayKey* destKey = &OverlayKey::UNSPECIFIED_KEY;
00562
00563 TransportAddress tempNode;
00564
00565 OverlayCtrlInfo* overlayCtrlInfo =
00566 dynamic_cast<OverlayCtrlInfo*>(call->getControlInfo());
00567
00568 if (overlayCtrlInfo &&
00569 overlayCtrlInfo->getTransportType() == ROUTE_TRANSPORT) {
00570
00571 if (overlayCtrlInfo->getSrcNode().isUnspecified())
00572 destNode = &(overlayCtrlInfo->getLastHop());
00573 else
00574 destNode = &(overlayCtrlInfo->getSrcNode());
00575 transportType = ROUTE_TRANSPORT;
00576 compType = static_cast<CompType>(overlayCtrlInfo->getSrcComp());
00577 if (static_cast<RoutingType>(overlayCtrlInfo->getRoutingType())
00578 == FULL_RECURSIVE_ROUTING) {
00579 destKey = &(overlayCtrlInfo->getSrcNode().getKey());
00580 destNode = &NodeHandle::UNSPECIFIED_NODE;
00581 }
00582 } else {
00583 UDPControlInfo* udpCtrlInfo =
00584 check_and_cast<UDPControlInfo*>(call->getControlInfo());
00585
00586 tempNode = TransportAddress(udpCtrlInfo->getSrcAddr(), udpCtrlInfo->getSrcPort());
00587 destNode = &tempNode;
00588
00589 }
00590
00591 sendRpcResponse(transportType, compType,
00592 *destNode, *destKey, call, response);
00593 }