RealworldConnector.cc

Go to the documentation of this file.
00001 //
00002 // Copyright (C) 2006 Institut fuer Telematik, Universitaet Karlsruhe (TH)
00003 //
00004 // This program is free software; you can redistribute it and/or
00005 // modify it under the terms of the GNU General Public License
00006 // as published by the Free Software Foundation; either version 2
00007 // of the License, or (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU General Public License for more details.
00013 //
00014 // You should have received a copy of the GNU General Public License
00015 // along with this program; if not, write to the Free Software
00016 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
00017 //
00018 
00024 #include <string.h>
00025 #include <omnetpp.h>
00026 
00027 #include "RealworldConnector.h"
00028 
00029 RealworldConnector::RealworldConnector()
00030 {
00031     packetNotification = NULL;
00032 }
00033 
00034 RealworldConnector::~RealworldConnector()
00035 {
00036     cancelAndDelete(packetNotification);
00037 }
00038 
00039 void RealworldConnector::initialize(int stage)
00040 {
00041     if (stage==3) {
00042         // update display string when addresses have been autoconfigured etc.
00043         updateDisplayString();
00044         return;
00045     }
00046 
00047     // all initialization is done in the first stage
00048     if (stage!=0)
00049         return;
00050 
00051     packetNotification = new cMessage("packetNotification");
00052     mtu = par("mtu");
00053 
00054     scheduler = check_and_cast<RealtimeScheduler *>(simulation.getScheduler());
00055     scheduler->setInterfaceModule(this, packetNotification, &packetBuffer,
00056                                   mtu, isApp());
00057 
00058     if (!isApp() ) {
00059         parser = check_and_cast<PacketParser*>(
00060                       getParentModule()->getSubmodule("packetParser"));
00061     } else {
00062         parser = check_and_cast<PacketParser*>(
00063                       getParentModule()->getSubmodule("applicationParser"));
00064     }
00065 
00066     numSent = numRcvdOK = numRcvError = numSendError = 0;
00067     WATCH(numSent);
00068     WATCH(numRcvdOK);
00069     WATCH(numRcvError);
00070     WATCH(numSendError);
00071 
00072     if (!isApp()) {
00073         gateIndexNetwOut = gate("netwOut")->getId();
00074     } else {
00075         gateIndexNetwOut = gate("to_lowerTier")->getId();
00076     }
00077 
00078 }
00079 
00080 
00081 void RealworldConnector::handleMessage(cMessage *msg)
00082 {
00083     // Packet from the real world...
00084     if (msg==packetNotification) {
00085         EV << "[RealworldConnector::handleMessage()]\n"
00086            << "    Message from outside. Queue length = "
00087            << packetBuffer.size() << endl;
00088 
00089         while( packetBuffer.size() > 0 ) {
00090             // get packet from buffer and parse it
00091 
00092             RealtimeScheduler::PacketBufferEntry packet = *(packetBuffer.begin());
00093             packetBuffer.pop_front();
00094             char* buf = packet.data;
00095             uint32_t len = packet.length;
00096             sockaddr* addr = packet.addr;
00097             socklen_t addrlen = packet.addrlen;
00098             cMessage *parsedPacket = decapsulate(buf, len, addr, addrlen);
00099             if (parsedPacket) {
00100                 numRcvdOK++;
00101                 send(parsedPacket, gateIndexNetwOut);
00102             } else {
00103                 numRcvError++;
00104             }
00105 
00106         }
00107     } else // arrived on gate "netwIn"
00108     {
00109         // Packet from inside, send to real word
00110         EV << "[RealworldConnector::handleMessage()]\n"
00111            << "    Received " << msg << " for transmission"
00112            << endl;
00113 
00114         transmitToNetwork(check_and_cast<cPacket*>(msg));
00115     }
00116 
00117     if (ev.isGUI())
00118         updateDisplayString();
00119 
00120 }
00121 
00122 void RealworldConnector::transmitToNetwork(cPacket *msg)
00123 {
00124     unsigned int length;
00125     sockaddr* addr = 0;
00126     socklen_t addrlen = 0;
00127     char* buf = encapsulate(msg, &length, &addr, &addrlen);
00128     if (buf) {
00129         numSent++;
00130         int nByte = scheduler->sendBytes(buf, length, addr, addrlen, isApp());
00131 
00132         if (nByte < 0) {
00133             EV << "[RealworldConnector::transmitToNetwork()]\n"
00134                << "    Error sending Packet, sendBytes returned " << nByte
00135                << endl;
00136 
00137             numSendError++;
00138         } else {
00139             EV << "[RealworldConnector::transmitToNetwork()]\n"
00140                << "    Packet (size = " << nByte << ") sent"
00141                << endl;
00142         }
00143     } else {
00144         numSendError++;
00145     }
00146 
00147     delete[] buf;
00148     delete addr;
00149 }
00150 
00151 void RealworldConnector::updateDisplayString()
00152 {
00153     char buf[80];
00154 
00155     if (ev.isDisabled()) {
00156         // speed up things
00157         getDisplayString().setTagArg("t",0,"");
00158     }
00159 
00160     sprintf(buf, "rcv:%ld snt:%ld", numRcvdOK, numSent);
00161 
00162     if (numRcvError>0)
00163         sprintf(buf+strlen(buf), "\nerrin:%ld errout:%ld", numRcvError,
00164                 numSendError);
00165 
00166     getDisplayString().setTagArg("t",0,buf);
00167 }
00168 
Generated on Wed May 26 16:21:15 2010 for OverSim by  doxygen 1.6.3