📄 physic.cpp
字号:
#include "h/physic.h"#include <string.h>//define the sting that define the host displayDefine_Module(Physic);cNeighbour::cNeighbour(){};cNeighbour::~cNeighbour(){};void Physic::initialize(){ hosts.setName("hosts"); nbList.setName("nblist"); hosts.takeOwnership(false); // FIXME this is a terrible hack to prevent crash on exit because of double deletion --Andras nbList.takeOwnership(false); cModule *parent = parentModule(); cModule *mod; char str[90]; posX = (int)parent->par("x"); posY = (int)parent->par("y"); numHost = (int)parent->par("numHost"); power = (double) par("txPower"); rxThreshold = (double) par("rxThreshold"); delay = &par("channelDelay"); error = &par("channelError"); dataRate = &par("channelDatarate"); gatesNum = 0; nbCount = 0; msgWithErr =0; //show the node on the map //sprintf(str,displayS,posX,posY,"red");
sprintf(str, displayS, posX, posY, IDLE_COLOR); parentModule()->setDisplayString(0,str,true); //fullfill the hosts vector detectNeighbours();}void Physic::handleMessage(cMessage* msg){ d("\t--- physic ---"); char str[50]; //update position and go on/*
if ( msg->arrivedOn("fromMobility") ) { d("msg from mobility"); posX = (int)msg->par("x"); posY= (int)msg->par("y"); update the position sprintf(str,displayS,posX, posY,"red"); parentModule()->setDisplayString(0,str,true); compute the trasmission range that might have been changed range = sqrt(power/rxThreshold); check which hosts are reachable updateConnections(); delete msg; } else*/ //send the messages to the neighbours
range = sqrt(power/rxThreshold);
updateConnections();
if ( msg->arrivedOn("fromMac") ) { d("msg from Mac");
Log("physic: message from Mac\n");
//compute the trasmission range range = sqrt(power/rxThreshold); //send the message to all the neighbouts broadcast(msg); if( msg!= NULL ); delete msg; } else { //arrived from outside the module d("msg from outside"); if(msg->hasBitError()) { d("received message with errors...discarding!"); msgWithErr++; delete msg; } else { d("got message from "<<msg->par("source")); send(msg,"toMac"); // FIXME it is illegal to send a msg object and keep referencing it!!! -Andras } }}void Physic::broadcast(cMessage*msg){ cNeighbour* n = NULL; d("broadcast Out"); for(int i =0; i < nbList.items() ;i++) { if(nbList[i]) { //a new copy of message has to be made cMessage* m = new cMessage(*msg); n = (cNeighbour*) nbList[i]; send(m,n->gateIndex); } }}void Physic::detectNeighbours(){ //pointer to the modules that are to be scanned cModule* mod; //stores the index returned by cArray.add() int pos = 0;
char tmpstr[128];
memset(tmpstr, 0x00, sizeof(tmpstr));
d("detectNeigh");
Log("Physic:detect Neighbours::\n"); for(int i=1; i<= simulation.lastModuleId(); i++) { //scan the simulation module vector mod = (cModule*)simulation.module(i); if( strcmp(mod->name(), "physic") == 0) { cNeighbour *n = new cNeighbour; n->ph = mod->id();
//remember its parent module too n->mobHost = mod->parentModule()->id(); n->gateIndex = -1;//not connected pos = hosts.add(n); if(i == id()) myI = pos; } }}void Physic::updateConnections(){ d("updateConnections"); cNeighbour* n; for(int i=0; i< numHost ; i++) { //check the link avoiding to analyze itself if ( ( i != myI) && checkConnection(i)){ n = (cNeighbour*)hosts[i]; d("link changed between this host and:"<<n->mobHost); //make the other node do the check if (n->mobHost < parentModule()->id()) { d("notify the disconnection to the remote node-"); Physic* remote = (Physic*)simulation.module(n->ph); // the index of this host on the remote hosts vector remote->checkConnection( myI ); } } }}//returns true if the connection has changed statebool Physic::checkConnection(int i){ d("checkConnection"); cNeighbour* n = (cNeighbour*)hosts[i];
int band; //avoid the parent to this module parent if( (n->ph != id()) && isReachable(id(),n->ph, band)) { //if it is not known if (nbList.find(n) == -1 ) { nbList.add(n); nbCount++; d("connecting to"<<n->mobHost); n->gateIndex= connectModules(n->ph,n->mobHost); } return true; } else { //check if it was connected int a = nbList.find(n); d("host not reachable "<<n->mobHost); if(a!= -1) { d("diconnect from neighbour:"<<n->mobHost); cNeighbour* tmp; //remove do not delete the object from the //memory! the list stores only a pointer to the //original host object. nbList.remove(a); //avoid holes in the array if( (nbCount>1) && (a!=nbCount-1)) { tmp = (cNeighbour*)nbList.remove(nbCount-1); nbList.addAt(a,tmp); } nbCount--; n->gateIndex = -1; //disconnect disconnectFrom(n->ph,n->mobHost); return true; } else { d("but "<<n->ph<<" was not connected"); return false; } }}int Physic::connectModules(int rPhysic,int rMod){ d("connectModules"); //a->b->c->d int a,b,c,d; //pointer to the remote physical layer Physic *ph = (Physic*)simulation.module(rPhysic); //pointer to the remote host object cModule* mod = (cModule*) simulation.module(rMod); //create the gates and the connection whithin these modules setUpConn('O',a,b); //do the same for the remote node. Note that 'c' will be used later for the conn //between the two mobile hosts. ph->setUpConn('I',d,c); if( (a == -1) || (b == -1) || (c == -1) || (d == -1) ) { ev << "Error in the connectModules function \n"; wait(2); } d(a<<"->"<<b<<"-->"<<c<<"->"<<d<<" OK!"); cBasicChannel *channel = new cSimpleChannel("channel"); channel->setDelay(delay->doubleValue()); channel->setDatarate(dataRate->doubleValue()); channel->setError(error->doubleValue()); parentModule()->gate(b)->connectTo(mod->gate(c), channel); //draw the link cGate *g = parentModule()->gate(b); g->setDisplayString( g->displayString(), true); d("b-->c connected --> end actual connect"); return a;}//kind = 'O' || 'I'void Physic::setUpConn(char kind,int& a,int& b){ char s[20],t[20]; cModule* parent = parentModule(); //a is the gate on the physic module, //b is on the compound module d("setUpConn"); //define the gate's name if(kind == 'I') strcpy(t,"Rx%d\0"); else strcpy(t,"Tx%d\0"); //create the gates to this module and its parent gatesNum++; sprintf(s,t,gatesNum); a = addNewGate(this,s,kind); b = addNewGate(parent,s,kind); d("added gate 'b' :"<<s); if( (a == -1)||(b == -1)) { d("Error in the addGateVector function "); wait(2); } //connect the gates if(kind == 'O') { this->gate(a)->connectTo(parent->gate(b)); //connect((cModule*)this,a,(cLinkType *)NULL,(cModule*)parent,b); d("ph->comp conneected!"); } else { //connect((cModule*)parent,b,(cLinkType *)NULL,(cModule*)this,a); parent->gate(b)->connectTo(this->gate(a)); d("comp->ph connected!"); }}int Physic::addNewGate(cModule *mod, char* gname, char type){ cGate* g; int index = 0, gateNum = 0; bool found = false; int i = 0; d("gates number before connection:"<<mod->gates()); //look for a free entry while((i< mod->gatev.items()) && (!found)) { g = (cGate*) mod->gate(i); d("gate: "<<i); if(g == NULL) { d("found a null gate vector place. Use it !"); g = new cGate(gname,type); mod->gatev.addAt(i,g); g->setOwnerModule( mod, i); index = i; found = true; } else if(!g->isConnected()) { d("found a not connected gate. recycling :"<<g->name()); delete g; g = new cGate(gname,type); mod->gatev.addAt(i,g); g->setOwnerModule( mod, i); found = true; index = i; } else i++; } //all the entries are used, add a new gate if(!found) { d("free place not found, adding a new one "); mod->addGate(gname,type); gateNum = mod->gates(); if(mod->hasGate(gname)) { d("has gate ok !"); index = mod->findGate(gname); } else { d("--- ERROR new gate not found!"); } } //mod->setGateSize(gname,mod->gates()); g = (cGate*) mod->gate(index); //g->setIndex(index,gateNum); //g->setIndex(index,mod->gates()); g->setOwnerModule(mod,index); //cGate* newGate = new cGate(gname, type); return index;}bool Physic::disconnectFrom(int rPhysic, int rMob){ int parent =(int) parentModule()->id(); int me = id(); d("-----diconnect------"); //disconect the link between the two nodes putDownConn(me,parent,rMob,rPhysic); d("Diconnection successfull!"); return true;}// Left -------> arrow -------> Rightbool Physic::putDownConn(int lph,int leftId, int rightId,int rph){ cModule *left = (cModule*)simulation.module(leftId); cModule *right = (cModule*)simulation.module(rightId); cModule *lPhysic = (cModule*)simulation.module(lph); cModule *rPhysic = (cModule*)simulation.module(rph); //a->b-->c->d int a =-1, b =-1, c =-1, d =-1; cGate *g; d("put down Connection between:"<<left->name()<<","<<left->id()<<" - "<<right->name()<<","<<right->id()); //look for the connection gate to delete if(!getGateIndex(left,right,a,b,c,d) ) { d("PutDown: gateindex retured false! ******************************"); return false; } d("deleting gates a:"<<a<<" b:"<<b<<" c"<<c<<" d"<<d); //tryal....// left->setDisplayString(left->displayString(),true);// right->setDisplayString(right->displayString(),true);// lPhysic->setDisplayString(lPhysic->displayString(),true);// rPhysic->setDisplayString(rPhysic->displayString(),true); g = (cGate*)lPhysic->gate(a); g->setTo(NULL); lPhysic->gatev.remove(a); delete g; //get rid of the old gate g = (cGate*)left->gatev.get(b); g->setTo(NULL); g->setFrom(NULL); left->gatev.remove(b); d(g->name()); delete g; g = (cGate*)right->gatev.get(c); right->gatev.remove(c); g->setTo(NULL); g->setFrom(NULL); d(g->name()); delete g; g = (cGate*)rPhysic->gatev.get(d); rPhysic->gatev.remove(d); g->setFrom(NULL); d(g->name()); delete g; // this was suggested by Varga to avoid the errors that come out using TkEnv // but it doesn't seem to work... //left->setDisplayString(left->displayString()); return true;}bool Physic::getGateIndex(cModule* left,cModule *right,int& a,int&b, int& c, int& d){ int gateNum = left->gates(); cGate *g,*farGate; bool found = false; int i = 0; d("In GetGateIndex from "<<left->name()<<" to "<<right->name()); while( (i< left->gatev.items()) &&( !found )) { d(i); g = (cGate *)left->gatev.get(i); if ((g != NULL) &&(g->type()== 'O') && (g->isConnected())) { d("maybe.... "<<g->name()); if(g->toGate()->ownerModule()->id() == right->id()) { //it's the right gate farGate = (cGate*) g->toGate(); d("gates to disconnect found"); a = g->fromGate()->id(); b = i; c = g->toGate()->id(); d = farGate->toGate()->id(); found = true; } } i++; } return found;}void Physic::finish(){ d("Physic says bye"); FILE* fout = fopen("collectedData.dat","a"); d("Messages with errors..."<<msgWithErr); fprintf(fout,"Messages with errors........ %d\n",msgWithErr); fclose(fout);}/* modify the function to check if reachable , in which band
i_band 0..0.5 Range or o_band 0.5--1
*/bool Physic::isReachable(int from, int to, int& band){ Physic *s = (Physic*) simulation.module(from); Physic *d = (Physic*) simulation.module(to); int x,y; double dist,a; bool r; d->getPos(x,y); //Pitagora @ work... dist = sqrt( (double) ((x - s->posX ) * (x - s->posX )) + ((y - s->posY ) * (y - s->posY )) ); a = sqrt( (double) ((d->posX - s->posX ) * (d->posX - s->posX )) + ((d->posY - s->posY ) * (d->posY - s->posY )) );
r = ( dist <= range);
if(r)
{
if (dist <= range/2) band=I_BAND;
else band=O_BAND;
} return r;}void Physic::getVect(int i, int& ph, int& mh){ cNeighbour * n = NULL; n = (cNeighbour*)hosts[i]; ph = n->ph; mh = n->mobHost;}void Physic::setPos(int x, int y){ posX = x; posY = y;}void Physic::getPos(int &x, int &y){ //x = posX; //y = posY;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -