VBF协议

该算法是一种需要完整定位的地理算法。

每个节点的位置通过 AOA技术或信号强度来估计。

与发送节点、转发节点和目标节点相关的位置信息被携带在数据包中。从发送节点到目标节点的传递路径,由一个向量确定,该向量位于路由管道内,管道内的每个节点都可以充当发送数据包的候选者。

如果接收到数据包的节点在路由管道内,则发送数据包;否则将他丢弃。
为了确保路由,每个数据包中包含了发送者、目标和转发节点的坐标信息。节点的位置或坐标是通过定位技术获得的。

路由过程中,使用了矢量路由和管道路由。矢量路由是从源节点到目的节点的直线,而路由管道是半径可调的圆柱体,具有矢量路由的中心性。数据包从源到目的地的路由由矢量路由确定。

接收到数据包后,接收节点计算其相对于前一个转发节点的位置。只要节点可以确定它与向量路由足够接近,那么该节点就被认为是一个新的转发节点,并将其放入数据包中并转发给下一个节点。否则,将删除数据包。在该协议中,所有转发节点都在路由管道内。那些不靠近路由向量的节点不会转发和删除接收到的数据包。

但是这些协议不需要关于所有节点位置的信息。VBF 是一种源路由协议。这意味着路由从源节点开始。每个数据包只携带简单的路由数据,包括SP、TP和FP三个字段,分别表示发送者、目标和转发节点的位置。为了支持节点移动性,每个数据包还包含一个称为 Range 的字段。当一个数据包到达 TP 字段指定的区域时,它将使用 range 字段内的值确定传输限制,然后将其广播到网络。通过估计它与路由向量和半径字段的距离,将能够确定它是否可以转发数据。

总的来说,在 VBF 协议中,在那些节点彼此靠近的网络中,距离路由向量足够近或在路由管道内的节点将转发数据包。但这将导致能耗增加、不必要的数据包传输量增加。因此,应针对密集网络采取适当的策略。一种分析和确定节点密度程度和调整布管半径的方法是采用自适应算法。

该算法使用期望因子来评估节点转发数据包的适合性。在S0 S1向量中, S1是发送节点, S0是目标节点,F 是前转发节点,节点 A 的期待因子计算如下:

p=节点A在S0 S1向量上的投影,w=节点的路由管道半径,R=节点F的传输范围,d=节点A到节点F的距离,cta=是fS0向量和fA向量的夹角。
根据期望因子的定义,可以观察到对于每个接近于路由向量的节点, 0<p<w,每个节点的可取因子都在[0, 3]的范围内。越接近 0,节点越接近合适的位置。

如果 VBF 协议中的转发节点在路由向量附近找到要转发的节点,它会将该数据包保留一段时间以保持自适应性。
基于矢量的路由协议对路由管道半径非常敏感。由于它们在路由管道内的状况,一些节点不断暴露在数据传输中,导致节点过早死亡。

vbf.cc*/#include "aqua-sim-routing-vbf.h"
#include "aqua-sim-header-routing.h"
#include "aqua-sim-header.h"
#include "aqua-sim-pt-tag.h"
#include "aqua-sim-propagation.h"#include "ns3/log.h"
#include "ns3/integer.h"
#include "ns3/double.h"
#include "ns3/mobility-model.h"
#include "ns3/simulator.h"using namespace ns3;NS_LOG_COMPONENT_DEFINE("AquaSimVBF");
//NS_OBJECT_ENSURE_REGISTERED(AquaSimPktHashTable);AquaSimPktHashTable::AquaSimPktHashTable() {NS_LOG_FUNCTION(this);m_windowSize=WINDOW_SIZE;//  lower_counter=0;// 50 items in the hash table, however, because it begins by 0, so, minus 1//Tcl_InitHashTable(&m_htable, 3);
}AquaSimPktHashTable::~AquaSimPktHashTable()
{NS_LOG_FUNCTION(this);for (std::map<hash_entry,vbf_neighborhood*>::iterator it=m_htable.begin(); it!=m_htable.end(); ++it) {delete it->second;}m_htable.clear();
}void
AquaSimPktHashTable::Reset()
{m_htable.clear();/*vbf_neighborhood *hashPtr;Tcl_HashEntry *entryPtr;Tcl_HashSearch searchPtr;entryPtr = Tcl_FirstHashEntry(&m_htable, &searchPtr);while (entryPtr != NULL) {hashPtr = (vbf_neighborhood *)Tcl_GetHashValue(entryPtr);delete hashPtr;Tcl_DeleteHashEntry(entryPtr);entryPtr = Tcl_NextHashEntry(&searchPtr);}*/
}vbf_neighborhood*
AquaSimPktHashTable::GetHash(AquaSimAddress senderAddr, unsigned int pk_num)
{hash_entry entry = std::make_pair (senderAddr,pk_num);std::map<hash_entry,vbf_neighborhood*>::iterator it;it = m_htable.find(entry);if (it == m_htable.end())return NULL;return it->second;/*unsigned int key[3];key[0] = senderAddr;key[1] = 0; //sender_id.port_;key[2] = pk_num;Tcl_HashEntry *entryPtr = Tcl_FindHashEntry(&m_htable, (char *)key);if (entryPtr == NULL )return NULL;return (vbf_neighborhood *)Tcl_GetHashValue(entryPtr);*/
}void
AquaSimPktHashTable::PutInHash(AquaSimAddress sAddr, unsigned int pkNum)
{//Tcl_HashEntry *entryPtr;// Pkt_Hash_Entry    *hashPtr;vbf_neighborhood* hashPtr;//unsigned int key[3];//bool newPtr = true;//key[1]=0; //(vbh->sender_id).port_;hash_entry entry = std::make_pair (sAddr,pkNum);std::map<hash_entry,vbf_neighborhood*>::iterator it;int k=pkNum-m_windowSize;if(k>0)    //TODO verify this in future work{for (int i=0; i<k; i++){entry.second = i;it = m_htable.find(entry);if(it != m_htable.end()){hashPtr = it->second;delete hashPtr;m_htable.erase(it);}}}entry.second = pkNum;hashPtr = GetHash(sAddr,pkNum);//entryPtr = Tcl_CreateHashEntry(&m_htable, (char *)key, &newPtr);if (hashPtr != NULL) {int m=hashPtr->number;if (m<MAX_NEIGHBOR) {hashPtr->number++;hashPtr->neighbor[m].x=0;hashPtr->neighbor[m].y=0;hashPtr->neighbor[m].z=0;}return;}hashPtr=new vbf_neighborhood[1];hashPtr[0].number=1;hashPtr[0].neighbor[0].x=0;hashPtr[0].neighbor[0].y=0;hashPtr[0].neighbor[0].z=0;std::pair<hash_entry,vbf_neighborhood*> newPair;newPair.first=entry; newPair.second=hashPtr;if (m_htable.insert(newPair).second == false){delete newPair.second;}//Tcl_SetHashValue(entryPtr, hashPtr);
}void
AquaSimPktHashTable::PutInHash(AquaSimAddress sAddr, unsigned int pkNum, Vector p)
{NS_LOG_DEBUG("PutinHash begin:" << sAddr << "," << pkNum << ",(" << p.x << "," << p.y << "," << p.z << ")");//Tcl_HashEntry *entryPtr;// Pkt_Hash_Entry    *hashPtr;vbf_neighborhood* hashPtr;//unsigned int key[3];//bool newPtr = true;//key[1]=0; //(vbh->sender_id).port_;hash_entry entry = std::make_pair (sAddr,pkNum);std::map<hash_entry,vbf_neighborhood*>::iterator it;int k=pkNum-m_windowSize;if(k>0){for (int i=0; i<k; i++){entry.second = i;it = m_htable.find(entry);if(it != m_htable.end()){hashPtr = it->second;delete hashPtr;m_htable.erase(it);}}}entry.second = pkNum;hashPtr = GetHash(sAddr,pkNum);//entryPtr = Tcl_CreateHashEntry(&m_htable, (char *)key, &newPtr);if (hashPtr != NULL){int m=hashPtr->number;// printf("hash_table: this is not old item, there are %d item inside\n",m);if (m<MAX_NEIGHBOR) {hashPtr->number++;hashPtr->neighbor[m].x=p.x;hashPtr->neighbor[m].y=p.y;hashPtr->neighbor[m].z=p.z;}return;}hashPtr=new vbf_neighborhood[1];hashPtr[0].number=1;hashPtr[0].neighbor[0].x=p.x;hashPtr[0].neighbor[0].y=p.y;hashPtr[0].neighbor[0].z=p.z;std::pair<hash_entry,vbf_neighborhood*> newPair;newPair.first=entry; newPair.second=hashPtr;if (m_htable.insert(newPair).second == false){delete newPair.second;}//Tcl_SetHashValue(entryPtr, hashPtr);
}AquaSimDataHashTable::AquaSimDataHashTable() {NS_LOG_FUNCTION(this);Reset();//Tcl_InitHashTable(&htable, MAX_ATTRIBUTE);
}AquaSimDataHashTable::~AquaSimDataHashTable()
{NS_LOG_FUNCTION(this);Reset();
}void
AquaSimDataHashTable::Reset()
{for (std::map<int*,int*>::iterator it=m_htable.begin(); it!=m_htable.end(); ++it) {delete it->first;delete it->second;}m_htable.clear();/*Tcl_HashEntry *entryPtr;Tcl_HashSearch searchPtr;entryPtr = Tcl_FirstHashEntry(&htable, &searchPtr);while (entryPtr != NULL) {Tcl_DeleteHashEntry(entryPtr);entryPtr = Tcl_NextHashEntry(&searchPtr);}*/
}int*
AquaSimDataHashTable::GetHash(int* attr)
{std::map<int*,int*>::iterator it;it = m_htable.find(attr);if (it == m_htable.end())return NULL;return it->second;
}void
AquaSimDataHashTable::PutInHash(int* attr)
{//bool newPtr = true;//Tcl_HashEntry* entryPtr=Tcl_CreateHashEntry(&htable, (char *)attr, &newPtr);if (m_htable.count(attr)>0)return;int *hashPtr=new int[1];hashPtr[0]=1;m_htable.insert(std::pair<int*,int*>(attr,hashPtr));//Tcl_SetHashValue(entryPtr, hashPtr);
}NS_OBJECT_ENSURE_REGISTERED(AquaSimVBF);AquaSimVBF::AquaSimVBF()
{// Initialize variables.//  printf("VB initialized\n");m_pkCount = 0;m_width=0;m_counter=0;m_priority=1.5;//m_useOverhear = 0;m_enableRouting = 1;m_targetPos = Vector();m_rand = CreateObject<UniformRandomVariable> ();
}TypeId
AquaSimVBF::GetTypeId(void)
{static TypeId tid = TypeId ("ns3::AquaSimVBF").SetParent<AquaSimRouting> ().AddConstructor<AquaSimVBF> ().AddAttribute ("HopByHop", "Hop by hop VBF setting. Default 0 is false.",IntegerValue(0),MakeIntegerAccessor(&AquaSimVBF::m_hopByHop),MakeIntegerChecker<int>()).AddAttribute ("EnableRouting", "Enable routing VBF setting. Default 1 is true.",IntegerValue(1),MakeIntegerAccessor(&AquaSimVBF::m_enableRouting),MakeIntegerChecker<int>()).AddAttribute ("Width", "Width of VBF. Default is 100.",DoubleValue(100),MakeDoubleAccessor(&AquaSimVBF::m_width),MakeDoubleChecker<double>()).AddAttribute ("TargetPos", "Position of target sink (x,y,z).",Vector3DValue(),MakeVector3DAccessor(&AquaSimVBF::m_targetPos),MakeVector3DChecker());return tid;//bind("m_useOverhear_", &m_useOverhear);
}int64_t
AquaSimVBF::AssignStreams (int64_t stream)
{NS_LOG_FUNCTION (this << stream);m_rand->SetStream(stream);return 1;
}bool
AquaSimVBF::Recv(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
{NS_LOG_FUNCTION(this);AquaSimHeader ash;VBHeader vbh;AquaSimPtTag ptag;packet->RemoveHeader(ash);if (ash.GetNumForwards() <= 0) {  //no headers //TODO create specalized Application instead of using this hack.ash.SetDirection(AquaSimHeader::DOWN);ash.SetNumForwards(1);ash.SetSAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));ash.SetDAddr(AquaSimAddress::ConvertFrom(dest));ash.SetTimeStamp(Simulator::Now());vbh.SetMessType(AS_DATA);vbh.SetSenderAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));vbh.SetForwardAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));vbh.SetTargetAddr(AquaSimAddress::ConvertFrom(dest));vbh.SetPkNum(packet->GetUid());Ptr<Object> sObject = GetNetDevice()->GetNode();Ptr<MobilityModel> sModel = sObject->GetObject<MobilityModel> ();vbh.SetOriginalSource(sModel->GetPosition());vbh.SetExtraInfo_f(sModel->GetPosition());vbh.SetExtraInfo_t(m_targetPos);vbh.SetExtraInfo_o(sModel->GetPosition());packet->AddHeader(vbh);} else {packet->PeekHeader(vbh);//ignoring forward iterator, but this can be simply changed if necessary}std::string msg;if(ash.GetDirection () == AquaSimHeader::DOWN){msg = ") transmitting packet: ";}else{msg = ") receiving packet: ";}NS_LOG_INFO("Me(" << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << msg<< ash.GetSize() << " bytes ; "<< ash.GetTxTime().GetSeconds() << " sec. ; Dest: "<< ash.GetDAddr().GetAsInt()<< " ; Src: " << ash.GetSAddr().GetAsInt()<< " ; Forwards: " << ash.GetNumForwards()<< " ; ");packet->AddHeader(ash);//unsigned char msg_type =vbh.GetMessType();  //unused//unsigned int dtype = vbh.GetDataType();  //unused//double t1=vbh.GetTs();  //unusedif( !m_enableRouting ) {if( vbh.GetMessType() != AS_DATA ) {packet=0;return false;}if( vbh.GetSenderAddr() == GetNetDevice()->GetAddress() ) {//packet->RemovePacketTag(ptag);ptag.SetPacketType(AquaSimPtTag::PT_UWVB);packet->ReplacePacketTag(ptag);MACprepare(packet);MACsend(packet, (m_rand->GetValue()*JITTER));}else if( vbh.GetTargetAddr() == GetNetDevice()->GetAddress() )  {DataForSink(packet);}return true;}vbf_neighborhood *hashPtr= PktTable.GetHash(vbh.GetSenderAddr(), vbh.GetPkNum());// Received this packet before ?if (hashPtr != NULL) {PktTable.PutInHash(vbh.GetSenderAddr(), vbh.GetPkNum(),vbh.GetExtraInfo().f);packet=0;return false;// printf("vectrobasedforward: this is duplicate packet\n");}else {// Never receive it before ? Put in hash table.//printf("vectrobasedforward: this is new packet\n");PktTable.PutInHash(vbh.GetSenderAddr(), vbh.GetPkNum(),vbh.GetExtraInfo().f);Ptr<Object> sObject = GetNetDevice()->GetNode();Ptr<MobilityModel> sModel = sObject->GetObject<MobilityModel> ();Vector forwarder = vbh.GetExtraInfo().f;packet->RemoveHeader(ash);packet->RemoveHeader(vbh);Vector d = Vector(sModel->GetPosition().x - forwarder.x,sModel->GetPosition().y - forwarder.y,sModel->GetPosition().z - forwarder.z);vbh.SetExtraInfo_d(d);packet->AddHeader(vbh);packet->AddHeader(ash);ConsiderNew(packet);}return true;
}void
AquaSimVBF::ConsiderNew(Ptr<Packet> pkt)
{NS_LOG_FUNCTION(this);AquaSimHeader ash;VBHeader vbh;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);unsigned char msg_type =vbh.GetMessType();//unsigned int dtype = vbh.GetDataType();  //unuseddouble l;//,h;  //unused//Pkt_Hash_Entry *hashPtr;vbf_neighborhood *hashPtr;//  Agent_List *agentPtr;// PrvCurPtr  RetVal;AquaSimAddress from_nodeAddr;//, forward_nodeAddr;Ptr<Packet> gen_pkt;VBHeader gen_vbh;//  printf("Vectorbasedforward:oops!\n");switch (msg_type) {case INTEREST:// printf("Vectorbasedforward:it is interest packet!\n");hashPtr = PktTable.GetHash(vbh.GetSenderAddr(), vbh.GetPkNum());NS_LOG_INFO("ConsiderNew: INTEREST, hashptr #=" << hashPtr->number);// Check if it comes from sink agent of this node// If so we have to keep it in sink listfrom_nodeAddr = vbh.GetSenderAddr();//forward_nodeAddr = vbh.GetForwardAddr();//  printf("Vectorbasedforward:it the from_nodeaddr is %d %d  and theb this node id is %d ,%d!\n", from_nodeAddr,from_nodeID.port_,THIS_NODE.addr_,THIS_NODE.port_ );if (GetNetDevice()->GetAddress() == from_nodeAddr) {MACprepare(pkt);MACsend(pkt,m_rand->GetValue()*JITTER);//  printf("vectorbasedforward: after MACprepare(pkt)\n");}else{//CalculatePosition(pkt); not necessary with mobilitymodel//printf("vectorbasedforward: This packet is from different node\n");if (IsTarget(pkt)){// If this node is target?l=Advance(pkt);//    if (!SendUp(p))//      NS_LOG_WARN("DataForSink: Something went wrong when passing packet up to dmux.");//  printf("vectorbasedforward:%d send out the source-discovery \n",here_.addr_);pkt->RemoveHeader(ash);pkt->RemoveHeader(vbh);vbh.SetMessType(SOURCE_DISCOVERY);pkt->AddHeader(vbh);pkt->AddHeader(ash);SetDelayTimer(pkt,l*JITTER);// !!! need to re-think}else{// CalculatePosition(pkt);// No the target forwaredl=Advance(pkt);//h=Projection(pkt);  //never used...if (IsCloseEnough(pkt)) {// printf("vectorbasedforward:%d I am close enough for the interest\n",here_.addr_);MACprepare(pkt);MACsend(pkt,m_rand->GetValue()*JITTER);//!!!! need to re-think}else {//  printf("vectorbasedforward:%d I am not close enough for the interest  \n",here_.addr_);pkt=0;}}}// pkt=0;return;case TARGET_DISCOVERY:// from other nodes hitted by the packet, it is supposed// to be the one hop away from the sink// printf("Vectorbasedforward(%d,%d):it is target-discovery  packet(%d)! it target id is %d  coordinate is %f,%f,%f and range is %f\n",here_.addr_,here_.port_,vbh.GetPkNum(),vbh.GetTargetAddr(),vbh.GetExtraInfo().t.x, vbh.GetExtraInfo().t.y,vbh.GetExtraInfo().t.z,vbh.GetRange());if (GetNetDevice()->GetAddress()==vbh.GetTargetAddr()) {//printf("Vectorbasedforward(%d,??%d):it is target-discovery  packet(%d)! it target id is %d  coordinate is %f,%f,%f and range is %f\n",here_.addr_,here_.port_,vbh.GetPkNum(),vbh.GetTargetAddr(),vbh.GetExtraInfo().t.x, vbh.GetExtraInfo().t.y,vbh.GetExtraInfo().t.z,vbh.GetRange());// AquaSimAddress *hashPtr= PktTable.GetHash(vbh.GetSenderAddr(), vbh.GetPkNum());// Received this packet before ?// if (hashPtr == NULL) {//CalculatePosition(pkt); not necessary with mobilitymodelDataForSink(pkt);NS_LOG_INFO("AquaSimVBF::ConsiderNew: target is " << GetNetDevice()->GetAddress());// } //New data Process this data//} else  {pkt=0;}return;case SOURCE_DISCOVERY:pkt=0;// other nodes already claim to be the source of this interest//   SourceTable.PutInHash(vbh);return;case DATA_READY://  printf("Vectorbasedforward(%d,%d):it is data ready packet(%d)! it target id is %d \n",here_.addr_,here_.port_,vbh->pk_num,vbh->target_id.addr_);from_nodeAddr = vbh.GetSenderAddr();if (GetNetDevice()->GetAddress() == from_nodeAddr) {// come from the same node, broadcast itMACprepare(pkt);MACsend(pkt,m_rand->GetValue()*JITTER);return;}//CalculatePosition(pkt); not necessary with mobilitymodelif (GetNetDevice()->GetAddress()==vbh.GetTargetAddr()){NS_LOG_INFO("AquaSimVBF::ConsiderNew: target is " << GetNetDevice()->GetAddress());DataForSink(pkt); // process it}else{// printf("Vectorbasedforward: %d is the not  target\n", here_.addr_);MACprepare(pkt);MACsend(pkt, m_rand->GetValue()*JITTER);}return;/*case DATA_READY :// put source_agent in source list of routing tableagentPtr = new Agent_List;AGT_ADDR(agentPtr) = vbh.GetSenderAddr();agentPtr->next = routing_table[dtype].source;routing_table[dtype].source = agentPtr;// !! this part will be modified laterGod::instance()->AddSource(dtype, (vbh.GetSenderAddr()));gen_pkt = PrepareMessage(dtype, vbh.GetSenderAddr(), DATA_REQUEST);gen_vbh = HDR_UWVB(gen_pkt);//      gen_vbh->report_rate = ORIGINAL;if (!SendUp(p))NS_LOG_WARN("DataForSink: Something went wrong when passing packet up to dmux.");pkt=0;return;*/case AS_DATA:NS_LOG_INFO("AquaSimVBF::ConsiderNew: data packet");// printf("Vectorbasedforward(%d,%d):it is data packet(%d)! it target id is %d  coordinate is %f,%f,%f and range is %f\n",here_.addr_,here_.port_,vbh->pk_num,vbh->target_id.addr_,vbh->info.tx, vbh->info.ty,vbh->info.tz,vbh->range);//  printf("Vectorbasedforward(%d):it is data packet(%d)\n",here_.addr_,vbh->pk_num);from_nodeAddr = vbh.GetSenderAddr();if (GetNetDevice()->GetAddress() == from_nodeAddr) {// come from the same node, broadcast itMACprepare(pkt);MACsend(pkt,0);return;}//CalculatePosition(pkt); not necessary with mobilitymodel//  printf("vectorbasedforward: after MACprepare(pkt)\n");l=Advance(pkt);//h=Projection(pkt);  //never used...if (GetNetDevice()->GetAddress()==vbh.GetTargetAddr()){// printf("Vectorbasedforward: %d is the target\n", here_.addr_);//+++++++++DataForSink(pkt); // process it}else{//  printf("Vectorbasedforward: %d is the not  target\n", here_.addr_);if (IsCloseEnough(pkt)) {Vector * p1;p1=new Vector[1];p1[0].x=vbh.GetExtraInfo().f.x;p1[0].y=vbh.GetExtraInfo().f.y;p1[0].z=vbh.GetExtraInfo().f.z;double delay=CalculateDelay(pkt,p1);  //TODO should just pass the Vector for easier memory management here.delete p1;double d2=(Distance(pkt)-m_device->GetPhy()->GetTransRange())/ns3::SOUND_SPEED_IN_WATER;//printf("Vectorbasedforward: I am  not  target delay is %f d2=%f distance=%f\n",(sqrt(delay)*DELAY+d2*2),d2,Distance(pkt));//++++++++++++++++++++++++//std::cout << "DElay is " << (sqrt(delay)*DELAY+d2*2) << " d2 is " << d2 << " distance is " << Distance(pkt) << "\n";//++SetDelayTimer(pkt,(sqrt(delay)*DELAY+d2*2));}else { pkt=0; }}return;default:pkt=0;break;}
}void
AquaSimVBF::Reset()
{PktTable.Reset();/*for (int i=0; i<MAX_DATA_TYPE; i++) {routing_table[i].Reset();}*/
}void
AquaSimVBF::Terminate()
{NS_LOG_DEBUG("AquaSimVBF::Terminate: Node=" << GetNetDevice()->GetAddress() <<": remaining energy=" << GetNetDevice()->EnergyModel()->GetEnergy() <<", initial energy=" << GetNetDevice()->EnergyModel()->GetInitialEnergy());
}void
AquaSimVBF::StopSource()
{/*Agent_List *cur;for (int i=0; i<MAX_DATA_TYPE; i++) {for (cur=routing_table[i].source; cur!=NULL; cur=AGENT_NEXT(cur) ) {SEND_MESSAGE(i, AGT_ADDR(cur), DATA_STOP);}}*/
}Ptr<Packet>
AquaSimVBF::CreatePacket()
{NS_LOG_FUNCTION(this);Ptr<Packet> pkt = Create<Packet>();if (pkt==NULL) return NULL;AquaSimHeader ash;VBHeader vbh;ash.SetSize(36);vbh.SetTs(Simulator::Now().ToDouble(Time::S));//!! I add new partvbh.SetExtraInfo_o(GetNetDevice()->GetPosition());vbh.SetExtraInfo_f(GetNetDevice()->GetPosition());pkt->AddHeader(vbh);pkt->AddHeader(ash);return pkt;
}Ptr<Packet>
AquaSimVBF::PrepareMessage(unsigned int dtype,AquaSimAddress to_addr,int msg_type)
{Ptr<Packet> pkt = Create<Packet>();VBHeader vbh;AquaSimHeader ash;vbh.SetMessType(msg_type);vbh.SetPkNum(m_pkCount);m_pkCount++;vbh.SetSenderAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));vbh.SetDataType(dtype);vbh.SetForwardAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));vbh.SetTs(Simulator::Now().ToDouble(Time::S));//    vbh->num_next = 1;// I am not sure if we need this// vbh->next_nodes[0] = to_addr;// I am not sure if we need it?/*iph->src_ = here_;iph->dst_ = to_addr;*/pkt->AddHeader(vbh);pkt->AddHeader(ash);return pkt;
}void
AquaSimVBF::MACprepare(Ptr<Packet> pkt)
{AquaSimHeader ash;VBHeader vbh;pkt->RemoveHeader(ash);pkt->RemoveHeader(vbh);vbh.SetForwardAddr(AquaSimAddress::ConvertFrom(GetNetDevice()->GetAddress()));ash.SetErrorFlag(false);// printf("vectorbased: the mac_Broadcast is:%d\n",MAC_BROADCAST);ash.SetNextHop(AquaSimAddress::GetBroadcast());//ash.addr_type() = NS_AF_ILINK;// ash.SetTxTime(Seconds(0));// printf("vectorbased: the address type is :%d and suppose to be %d and  nexthop %d MAC_BROAD %d\n", ash->addr_type(),NS_AF_ILINK,ash->next_hop(),MAC_BROADCAST);ash.SetDirection(AquaSimHeader::DOWN);/*if(!GetNetDevice()->GetSinkStatus()) {       //!! I add new partf = Vector(GetNetDevice()->CX(),GetNetDevice()->CY(),GetNetDevice()->CZ());}else{*/Ptr<MobilityModel> model = GetNetDevice()->GetNode()->GetObject<MobilityModel>();//}vbh.SetExtraInfo_f(model->GetPosition());pkt->AddHeader(vbh);pkt->AddHeader(ash);// printf("vectorbasedforward: last line MACprepare\n");
}void
AquaSimVBF::MACsend(Ptr<Packet> pkt, double delay)
{NS_LOG_INFO("MACsend: delay " << delay << " at time " << Simulator::Now().GetSeconds());AquaSimHeader ash;VBHeader vbh;//AquaSimPtTag ptag;pkt->RemoveHeader(ash);pkt->RemoveHeader(vbh);//pkt->RemovePacketTag(ptag);// I don't understand why it works like this way/*if (vbh.GetMessType() == AS_DATA)ash->size() = (God::instance()->data_pkt_size) + 4*(vbh.GetPkNum() - 1);elseash->size() = 36 + 4*(vbh.GetPkNum() -1);*//*if (vbh.GetMessType() == AS_DATA)// ash->size() = (God::instance()->data_pkt_size)+12 ;ash->size() = 65+12 ;elseash->size() =32;*///if(!ll) printf("ok, the LL is empty\n");//ptag.SetPacketType(PT_UWVB);//printf("vectorbased: the address type is :%d uid is %d\n", ash->addr_type(),pkt->uid_);//printf("vectorbased: the packet type is :%d\n", ptag.GetPacketType());// ll->handle(pkt);pkt->AddHeader(vbh);pkt->AddHeader(ash);Simulator::Schedule(Seconds(delay),&AquaSimRouting::SendDown,this,pkt,ash.GetNextHop(),Seconds(0));
}void
AquaSimVBF::DataForSink(Ptr<Packet> pkt)
{if (!SendUp(pkt))NS_LOG_WARN("DataForSink: Something went wrong when passing packet up to dmux.");
}void
AquaSimVBF::SetDelayTimer(Ptr<Packet> pkt, double c)
{NS_LOG_FUNCTION(this << c);if(c<0)c=0;Simulator::Schedule(Seconds(c),&AquaSimVBF::Timeout,this,pkt);
}void
AquaSimVBF::Timeout(Ptr<Packet> pkt)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);unsigned char msg_type =vbh.GetMessType();vbf_neighborhood  *hashPtr;//Ptr<Packet> p1;switch (msg_type) {case AS_DATA:hashPtr= PktTable.GetHash(vbh.GetSenderAddr(), vbh.GetPkNum());if (hashPtr != NULL) {int num_neighbor=hashPtr->number;// printf("vectorbasedforward: node %d have received %d when wake up at %f\n",here_.addr_,num_neighbor,NOW);if (num_neighbor!=1) {/*AlohaOverhear can guarantee that the packet be successfully deliveried to next hop,* so we release the pkt if overhearing other neighbors send this pkt.*//* if( m_useOverhear ){pkt=0;return;}*/// Some guys transmit the data before meif (num_neighbor==MAX_NEIGHBOR) {//I have too many neighbors, I quitpkt=0;return;}else //I need to calculate my delay time again{int i=0;Vector* tp;tp=new Vector[1];tp[0].x=hashPtr->neighbor[i].x;tp[0].y=hashPtr->neighbor[i].y;tp[0].z=hashPtr->neighbor[i].z;double tdelay=CalculateDelay(pkt,tp);// double tdelay=5;i++;double c=1;while (i<num_neighbor) {c=c*2;tp[0].x=hashPtr->neighbor[i].x;tp[0].y=hashPtr->neighbor[i].y;tp[0].z=hashPtr->neighbor[i].z;double t2delay=CalculateDelay(pkt,tp);if (t2delay<tdelay)tdelay=t2delay;i++;}delete tp;if(tdelay<=(m_priority/c)) {MACprepare(pkt);MACsend(pkt,0);}else{pkt=0; //to much overlap, don;t send}}// end of calculate my new delay time}else{// I am the only neighborVector* tp;tp=new Vector[1];tp[0].x=vbh.GetExtraInfo().f.x;tp[0].y=vbh.GetExtraInfo().f.y;tp[0].z=vbh.GetExtraInfo().f.z;double delay=CalculateDelay(pkt,tp);delete tp;if (delay<=m_priority) {// printf("vectorbasedforward: !!%f\n",delay);MACprepare(pkt);MACsend(pkt,0);}else  {pkt=0; }// printf("vectorbasedforward:  I%d am the only neighbor, I send it out at %f\n",here_.addr_,NOW);return;}}break;default:pkt=0;break;}
}void
AquaSimVBF::CalculatePosition(Ptr<Packet> pkt)
{//not used.VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);double fx=vbh.GetExtraInfo().f.x;double fy=vbh.GetExtraInfo().f.y;double fz=vbh.GetExtraInfo().f.z;double dx=vbh.GetExtraInfo().d.x;double dy=vbh.GetExtraInfo().d.y;double dz=vbh.GetExtraInfo().d.z;GetNetDevice()->CX()=fx+dx;GetNetDevice()->CY()=fy+dy;GetNetDevice()->CZ()=fz+dz;// printf("vectorbased: my position is computed as (%f,%f,%f)\n",GetNetDevice()->CX_, GetNetDevice()->CY_,GetNetDevice()->CZ_);
}double
AquaSimVBF::CalculateDelay(Ptr<Packet> pkt,Vector* p1)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);double fx=p1->x;double fy=p1->y;double fz=p1->z;Vector pos = GetNetDevice()->GetPosition();double dx=pos.x-fx;double dy=pos.y-fy;double dz=pos.z-fz;double tx=vbh.GetExtraInfo().t.x;double ty=vbh.GetExtraInfo().t.y;double tz=vbh.GetExtraInfo().t.z;double dtx=tx-fx;double dty=ty-fy;double dtz=tz-fz;double dp=dx*dtx+dy*dty+dz*dtz;// double a=Advance(pkt);double p=Projection(pkt);double d=sqrt((dx*dx)+(dy*dy)+ (dz*dz));double l=sqrt((dtx*dtx)+(dty*dty)+ (dtz*dtz));double cos_theta;if (d ==0 || l==0) cos_theta=0;else cos_theta=dp/(d*l);// double delay=(TRANSMISSION_DISTANCE-d*cos_theta)/TRANSMISSION_DISTANCE;double delay=(p/m_width) +((m_device->GetPhy()->GetTransRange()-d*cos_theta)/m_device->GetPhy()->GetTransRange());// double delay=(p/m_width) +((TRANSMISSION_DISTANCE-d)/TRANSMISSION_DISTANCE)+(1-cos_theta);//printf("vectorbased: node(%d) projection is %f, and cos is %f, and d is %f)\n",here_.addr_,p, cos_theta, d);NS_LOG_DEBUG("CalculateDelay(" << GetNetDevice()->GetAddress() << ") projection is "<< p << ", cos is " << cos_theta << " and d is " << d << " and total delay is " << delay);return delay;
}double
AquaSimVBF::Distance(Ptr<Packet> pkt)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);double tx=vbh.GetExtraInfo().f.x;double ty=vbh.GetExtraInfo().f.y;double tz=vbh.GetExtraInfo().f.z;// printf("vectorbased: the target is %lf,%lf,%lf \n",tx,ty,tz);Vector pos = GetNetDevice()->GetPosition();//double x=GetNetDevice()->CX(); //change later//double y=GetNetDevice()->CY();// printf(" Vectorbasedforward: I am in advanced\n");//double z=GetNetDevice()->CZ();// printf("the target is %lf,%lf,%lf and my coordinates are %lf,%lf,%lf\n",tx,ty,tz,x,y,z);return sqrt((tx-pos.x)*(tx-pos.x)+(ty-pos.y)*(ty-pos.y)+ (tz-pos.z)*(tz-pos.z));
}double
AquaSimVBF::Advance(Ptr<Packet> pkt)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);double tx=vbh.GetExtraInfo().t.x;double ty=vbh.GetExtraInfo().t.y;double tz=vbh.GetExtraInfo().t.z;// printf("vectorbased: the target is %lf,%lf,%lf \n",tx,ty,tz);Vector pos = GetNetDevice()->GetPosition();//double x=GetNetDevice()->CX(); //change later//double y=GetNetDevice()->CY();// printf(" Vectorbasedforward: I am in advanced\n");//double z=GetNetDevice()->CZ();// printf("the target is %lf,%lf,%lf and my coordinates are %lf,%lf,%lf\n",tx,ty,tz,x,y,z);return sqrt((tx-pos.x)*(tx-pos.x)+(ty-pos.y)*(ty-pos.y)+ (tz-pos.z)*(tz-pos.z));
}double
AquaSimVBF::Projection(Ptr<Packet> pkt)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);double tx=vbh.GetExtraInfo().t.x;double ty=vbh.GetExtraInfo().t.y;double tz=vbh.GetExtraInfo().t.z;Vector o;//double ox, oy, oz;if( !m_hopByHop ){//printf("vbf is used\n");o.x=vbh.GetExtraInfo().o.x;o.y=vbh.GetExtraInfo().o.y;o.z=vbh.GetExtraInfo().o.z;}else{//printf("m_hopByHop vbf is used\n");o.x=vbh.GetExtraInfo().f.x;o.y=vbh.GetExtraInfo().f.y;o.z=vbh.GetExtraInfo().f.z;}//NOTE below may not work if the nodes are mobile./*double x=GetNetDevice()->CX();double y=GetNetDevice()->CY();double z=GetNetDevice()->CZ();*/Vector myPos = GetNetDevice()->GetPosition();double wx=tx-o.x;double wy=ty-o.y;double wz=tz-o.z;double vx=myPos.x-o.x;double vy=myPos.y-o.y;double vz=myPos.z-o.z;double cross_product_x=vy*wz-vz*wy;double cross_product_y=vz*wx-vx*wz;double cross_product_z=vx*wy-vy*wx;double area=sqrt(cross_product_x*cross_product_x+cross_product_y*cross_product_y+cross_product_z*cross_product_z);double length=sqrt((tx-o.x)*(tx-o.x)+(ty-o.y)*(ty-o.y)+ (tz-o.z)*(tz-o.z));// printf("vectorbasedforward: the area is %f and length is %f\n",area,length);NS_LOG_DEBUG("Projection: area is " << area << " length is " << length);if (length==0) return 0;return area/length;
}bool
AquaSimVBF::IsTarget(Ptr<Packet> pkt)
{VBHeader vbh;AquaSimHeader ash;pkt->RemoveHeader(ash);pkt->PeekHeader(vbh);pkt->AddHeader(ash);if (vbh.GetTargetAddr().GetAsInt()==0) {printf("vectorbased: advanced is %lf and my range is %f\n",Advance(pkt),(double)vbh.GetRange());return (Advance(pkt)<vbh.GetRange());}else return(GetNetDevice()->GetAddress()==vbh.GetTargetAddr());
}bool
AquaSimVBF::IsCloseEnough(Ptr<Packet> pkt)
{//VBHeader vbh;//AquaSimHeader ash;//pkt->RemoveHeader(ash);//pkt->PeekHeader(vbh);//pkt->AddHeader(ash);//double range=vbh.GetRange();  //unused//double range=m_width;//  printf("underwatersensor: The m_width is %f\n",range);//double ox=vbh.GetExtraInfo().o.x;  //unused//double oy=vbh.GetExtraInfo().o.y;  //unused//double oz=vbh.GetExtraInfo().o.z;  //unused/*double tx=vbh.GetExtraInfo().t.x;double ty=vbh.GetExtraInfo().t.y;double tz=vbh.GetExtraInfo().t.z;double fx=vbh.GetExtraInfo().f.x;double fy=vbh.GetExtraInfo().f.y;double fz=vbh.GetExtraInfo().f.z;*/  //currently unused...//double x=GetNetDevice()->CX();  //unused  //change later//double y=GetNetDevice()->CY();  //unused//double z=GetNetDevice()->CZ();  //unused//double d=sqrt((tx-fx)*(tx-fx)+(ty-fy)*(ty-fy)+(tz-fz)*(tz-fz));  //unused//double l=sqrt((tx-ox)*(tx-ox)+(ty-oy)*(ty-oy)+ (tz-oz)*(tz-oz));//double l=Advance(pkt);  //unused// if (l<range)// {// printf("vectorbasedforward: IsClose?too close! it should be target!\n");// return true;// }// else {//double c=d/l;double c=1;// if ((d<=range)&&((z-oz)<0.01))  return true;if ((Projection(pkt)<=(c*m_width)))  return true;return false;}void AquaSimVBF::DoDispose()
{m_rand=0;AquaSimRouting::DoDispose();
}void AquaSimVBF::SetTargetPos(Vector pos)
{m_targetPos = pos;
}// Some methods for Flooding Entry/*void Vectorbasedforward_Entry::reset(){clear_agentlist(source);clear_agentlist(sink);source = NULL;sink = NULL;}void Vectorbasedforward_Entry::clear_agentlist(Agent_List *list){Agent_List *cur=list;Agent_List *temp = NULL;while (cur != NULL) {temp = AGENT_NEXT(cur);delete cur;cur = temp;}}*/
/* -*- Mode:C++; vbf.h-*- */*/#ifndef AQUA_SIM_ROUTING_VBF_H
#define AQUA_SIM_ROUTING_VBF_H#include "aqua-sim-routing.h"
#include "aqua-sim-address.h"
#include "aqua-sim-datastructure.h"
#include "aqua-sim-channel.h"
#include "ns3/vector.h"
#include "ns3/random-variable-stream.h"
#include "ns3/packet.h"#include <map>namespace ns3 {class VBHeader;struct vbf_neighborhood{int number;Vector neighbor[MAX_NEIGHBOR];
};typedef std::pair<AquaSimAddress, unsigned int> hash_entry;/*** \ingroup aqua-sim-ng** \brief Packet Hash table for VBF to assist in specialized tables.*/
class AquaSimPktHashTable {public:std::map<hash_entry,vbf_neighborhood*> m_htable;//std::map<hash_t, hash_entry> m_htable;AquaSimPktHashTable();~AquaSimPktHashTable();int  m_windowSize;void Reset();void PutInHash(AquaSimAddress sAddr, unsigned int pkNum);void PutInHash(AquaSimAddress sAddr, unsigned int pkNum, Vector p);vbf_neighborhood* GetHash(AquaSimAddress senderAddr, unsigned int pkt_num);
//private:
//int lower_counter;
};  // class AquaSimPktHashTable/*** \brief Packet Hash table for VBF to assist in specialized tables.*/
class AquaSimDataHashTable {public:std::map<int*,int*> m_htable;//Tcl_HashTable htable;AquaSimDataHashTable();~AquaSimDataHashTable();void Reset();void PutInHash(int *attr);int* GetHash(int *attr);
};  // class AquaSimDataHashTable/*** \brief Vector Based Forwarding* http://engr.uconn.edu/~jcui/UWSN_papers/vbf_networking2006.pdf*/
class AquaSimVBF : public AquaSimRouting {public:AquaSimVBF();static TypeId GetTypeId(void);int64_t AssignStreams (int64_t stream);virtual bool Recv(Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber);void SetTargetPos(Vector pos);// AquaSimVBF_Entry routing_table[MAX_DATA_TYPE];protected:int m_pkCount;int m_counter;int m_hopByHop;int m_enableRouting;   //if true, VBF can perform routing functionality. Otherwise, not perform//int m_useOverhear;double m_priority;bool m_measureStatus;// int m_portNumber;AquaSimPktHashTable PktTable;AquaSimPktHashTable SourceTable;AquaSimPktHashTable Target_discoveryTable;AquaSimPktHashTable SinkTable;double m_width;// the width is used to test if the node is close enough to the path specified by the packetVector m_targetPos;Ptr<UniformRandomVariable> m_rand;void Terminate();void Reset();void ConsiderNew(Ptr<Packet> pkt);void SetDelayTimer(Ptr<Packet>,double);void Timeout(Ptr<Packet>);double Advance(Ptr<Packet> );double Distance(Ptr<Packet> );double Projection(Ptr<Packet>);double CalculateDelay(Ptr<Packet>, Vector*);//double RecoveryDelay(Ptr<Packet>, Vector*);void CalculatePosition(Ptr<Packet>);void SetMeasureTimer(Ptr<Packet>,double);bool IsTarget(Ptr<Packet>);bool IsCloseEnough(Ptr<Packet>);Ptr<Packet> CreatePacket();Ptr<Packet> PrepareMessage(unsigned int dtype, AquaSimAddress to_addr, int msg_type);void DataForSink(Ptr<Packet> pkt);void StopSource();void MACprepare(Ptr<Packet> pkt);void MACsend(Ptr<Packet> pkt, double delay=0);virtual void DoDispose();
};  // class AquaSimVBF}  // namespace ns3#endif /* AQUA_SIM_ROUTING_VBF_H */
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
vbftest.cc*/#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/mobility-module.h"
#include "ns3/energy-module.h"  //may not be needed here...
#include "ns3/aqua-sim-ng-module.h"
#include "ns3/applications-module.h"
#include "ns3/log.h"
#include "ns3/callback.h"
#include <fstream>//++
#include "ns3/netanim-module.h"//++/** VBF Test*/using namespace ns3;NS_LOG_COMPONENT_DEFINE("VBF");int
main (int argc, char *argv[])
{//AnimationInterface anim ("vbf_animation.xml");double simStop = 200; //secondsint nodes = 200;int sinks = 1;uint32_t m_dataRate = 10000;uint32_t m_packetSize = 50;double range = 100;//int m_maxBurst =10;LogComponentEnable ("VBF", LOG_LEVEL_INFO);//to change on the fly/* CommandLine cmd;cmd.AddValue ("simStop", "Length of simulation", simStop);cmd.AddValue ("nodes", "Amount of regular underwater nodes", nodes);cmd.AddValue ("sinks", "Amount of underwater sinks", sinks);cmd.Parse(argc,argv);
*/std::cout << "-----------Initializing simulation-----------\n";NodeContainer nodesCon;NodeContainer sinksCon;NodeContainer senderCon;nodesCon.Create(nodes);sinksCon.Create(sinks);senderCon.Create(1);PacketSocketHelper socketHelper;socketHelper.Install(nodesCon);socketHelper.Install(sinksCon);socketHelper.Install(senderCon);//establish layers using helper's pre-build settingsAquaSimChannelHelper channel = AquaSimChannelHelper::Default();channel.SetPropagation("ns3::AquaSimRangePropagation");AquaSimHelper asHelper = AquaSimHelper::Default();//AquaSimEnergyHelper energy;   //******this could instead be handled by node helper. ****/asHelper.SetChannel(channel.Create());asHelper.SetMac("ns3::AquaSimBroadcastMac");
//  asHelper.SetMac("ns3::AquaSimRoutingMac", "max_range", DoubleValue(range), "optimal_metric", DoubleValue(range/4));asHelper.SetRouting("ns3::AquaSimVBF", "Width", DoubleValue(100), "TargetPos", Vector3DValue(Vector(190,190,0)));//VBF//asHelper.SetRouting("ns3::AquaSimDBR");//DBR/** Preset up mobility model for nodes and sinks here*/MobilityHelper mobility;MobilityHelper nodeMobility;NetDeviceContainer devices;Ptr<ListPositionAllocator> position = CreateObject<ListPositionAllocator> ();std::cout << "Creating Nodes\n";for (NodeContainer::Iterator i = nodesCon.Begin(); i != nodesCon.End(); i++){Ptr<AquaSimNetDevice> newDevice = CreateObject<AquaSimNetDevice>();devices.Add(asHelper.Create(*i, newDevice));newDevice->GetPhy()->SetTransRange(range);}for (NodeContainer::Iterator i = sinksCon.Begin(); i != sinksCon.End(); i++){Ptr<AquaSimNetDevice> newDevice = CreateObject<AquaSimNetDevice>();position->Add(Vector(190,190,0));devices.Add(asHelper.Create(*i, newDevice));newDevice->GetPhy()->SetTransRange(range);}Ptr<AquaSimNetDevice> newDevice = CreateObject<AquaSimNetDevice>();position->Add(Vector(10,10,0));devices.Add(asHelper.Create(senderCon.Get(0),newDevice));newDevice->GetPhy()->SetTransRange(range);//Set sink at origin and surround with uniform distribution of regular nodes.mobility.SetPositionAllocator(position);mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");nodeMobility.SetPositionAllocator("ns3::UniformDiscPositionAllocator", "X", DoubleValue(100.0),"Y", DoubleValue(100.0), "rho", DoubleValue(100));nodeMobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");nodeMobility.Install(nodesCon);mobility.Install(sinksCon);mobility.Install(senderCon);PacketSocketAddress socket;socket.SetAllDevices();// socket.SetSingleDevice (devices.Get(0)->GetIfIndex());socket.SetPhysicalAddress (devices.Get(nodes)->GetAddress());socket.SetProtocol (0);//std::cout << devices.Get(nodes)->GetAddress() << " &&& " << devices.Get(0)->GetIfIndex() << "\n";//std::cout << devices.Get(0)->GetAddress() << " &&& " << devices.Get(1)->GetIfIndex() << "\n";OnOffHelper app ("ns3::PacketSocketFactory", Address (socket));app.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.0066]"));app.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.9934]"));
//  app.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.026]"));
//  app.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0.974]"));app.SetAttribute ("DataRate", DataRateValue (m_dataRate));app.SetAttribute ("PacketSize", UintegerValue (m_packetSize));ApplicationContainer apps = app.Install (senderCon);apps.Start (Seconds (0.5));apps.Stop (Seconds (simStop));Ptr<Node> sinkNode = sinksCon.Get(0);TypeId psfid = TypeId::LookupByName ("ns3::PacketSocketFactory");Ptr<Socket> sinkSocket = Socket::CreateSocket (sinkNode, psfid);sinkSocket->Bind (socket);Packet::EnablePrinting ();  //for debugging purposesstd::cout << "-----------Running Simulation-----------\n";Simulator::Stop(Seconds(simStop));//ascii.EnableAsciiAll (ascii.CreateFileStream("VBF-TEST.tr"));AnimationInterface anim ("vbf_animation.xml");Simulator::Run();
anim.EnablePacketMetadata(true);
anim.EnableIpv4L3ProtocolCounters(Seconds(0),Seconds(simStop));
anim.EnableWifiMacCounters(Seconds(0),Seconds(simStop));
anim.EnableWifiPhyCounters(Seconds(0),Seconds(simStop));
//anim.EnablePcapAll("vbf_animation");
anim.UpdateNodeColor(0, 0, 255, 0); //设置节点颜色
anim.UpdateNodeSize(0, 30, 30); //设置节点大小
anim.UpdateNodeDescription (0, "Sender"); //设置节点描述
anim.UpdateNodeColor(1, 255, 0, 0);
anim.UpdateNodeSize(1, 30, 30);
anim.UpdateNodeDescription(1, "Sink");
anim.UpdateNodeColor(2, 0, 0, 255);
anim.UpdateNodeSize(2, 30, 30);
anim.UpdateNodeDescription(2, "Regular Node");asHelper.GetChannel()->PrintCounters();Simulator::Destroy();std::cout << "fin.\n";return 0;
}

运行结果

水声网络路由协议 vbf 原理与代码相关推荐

  1. TCP网络编程相关概念原理及其代码实现

    一.ip地址 IP地址:是标识网络设备的一个地址,作用是标识网络中唯一的一台设备,即通过IP地址就可以找到网络中的某台设备 分类 IPv4:网际协议版本4,是网际协议开发过程中的第四个修订版本,也是该 ...

  2. Tensorflow2.0---SSD网络原理及代码解析(二)-锚点框的生成

    Tensorflow2.0-SSD网络原理及代码解析(二)-锚点框的生成 分析完SSD网络的原理之后,一起来看看代码吧~ 代码转载于:https://github.com/bubbliiiing/ss ...

  3. 【资源】Faster R-CNN原理及代码讲解电子书

    <Faster R-CNN原理及代码讲解>是首发于GiantPandaCV公众号的教程,针对陈云大佬实现的Faster R-CNN代码讲解,Github链接如下: https://gith ...

  4. 【深度学习】搞懂 Vision Transformer 原理和代码,看这篇技术综述就够了

    作者丨科技猛兽 编辑丨极市平台 导读 本文对Vision Transformer的原理和代码进行了非常全面详细的解读,一切从Self-attention开始.Transformer的实现和代码以及Tr ...

  5. SSD算法原理与代码(三)

    说明:这几篇文章是讲解SSD,从算法原理.代码到部署到rk3588芯片上的过程.环境均是TF2.2,具体的安装过程请参考网上其他的文章. 一.SSD简介 SSD算法是一个优秀的one-stage目标检 ...

  6. LoRa SX1278/76驱动原理 附代码

    LoRa SX1278/76驱动原理 附代码 原理解释 LoRa 关键参数说明 前导码: 报头: 显式报头模式: 隐式报头模式: LoRa 调制解调: 扩频因子: 编码率: 信号带宽: 代码说明 SP ...

  7. Pytorch|YOWO原理及代码详解(二)

    Pytorch|YOWO原理及代码详解(二) 本博客上接,Pytorch|YOWO原理及代码详解(一),阅前可看. 1.正式训练 if opt.evaluate:logging('evaluating ...

  8. batchnorm原理及代码详解

    转载自:http://www.ishenping.com/ArtInfo/156473.html batchnorm原理及代码详解 原博文 原微信推文 见到原作者的这篇微信小文整理得很详尽.故在csd ...

  9. 洪水攻击程序c语言,洪水攻击原理及代码实现全攻略(附源代码)

    下载本文示例代码 推荐:应用程序安全的魔道之争 声明:本文所提供的资料仅仅限于技术交流和学习,请不要用于其他非法目的,维护网络安全是我们的共同责任. 下载本文源代码和例程 一. 什么是洪水攻击 洪水之 ...

最新文章

  1. 强烈推荐10个新媒体运营必备工具,极大提高工作效率
  2. 第二百九十、一、二天 how can I 坚持
  3. vue实现时间选择器,精确到秒
  4. python中的matplotlib(1)
  5. 安卓键盘加上数字_Android自定义键盘的实现(数字键盘和字母键盘)
  6. 利用bootstraptable展示数据,对数据进行排序分页等操作
  7. 进程创建fork--文件表项继承
  8. 作者:周一懋(1982-),男,江苏汇誉通数据科技有限公司大数据事业部总监、工程师...
  9. 由IDC机房测试谈主动工作教学实战案例!
  10. centos8 ssh配置_JumpServer 堡垒机CentOS 8 安装部署(四)
  11. Python minidom模块(DOM写入和解析XML)
  12. g4600黑苹果efi_在黑苹果系统下挂载和打开EFI(ESP)分区
  13. 卫星通信中信关站、关口站、地面终端的区分
  14. CAD如何自定义快捷键
  15. python自动化操作网页(谷歌浏览器)
  16. 中间继电器DZY-204/DC110V
  17. JAVASCRIPT精彩200例
  18. Linux红帽认证工程师(RHCE)考试笔记(Ansible学习笔记)
  19. 微机原理 单片机笔记
  20. Solr初探(五)---Solr7.5利用DIH导入结构化数据构建索引

热门文章

  1. Linux的删除命令
  2. 邢台学院计算机分数,邢台学院2018年各专业录取分数线
  3. Linux移动文件与目录-mv命令的10个实用例子
  4. android 删除短信 数据库,删除的短信如何恢复?Android手机短信删除了怎么恢复...
  5. CAD高版本窗体阵列LISP_高版本CAD如何显示阵列窗口?
  6. 交换式以太网和共享式以太网区别
  7. C/C++语言基础进阶算法备赛面试 经典、实用、趣味 程序设计编程300例精解每日一练第37天
  8. 第一次当项目经理压力大_你真的适合做项目经理吗?
  9. 基于STM32+Python+MySQL实现在线温度计设计和制作【100010362】
  10. 宏基暗影骑士3050ti-ubuntu20.04安装显卡驱动