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