Hi all,
I'm using
https://github.com/rmartin5/aqua-sim-ng, specifically AquaSimVBF, which uses on-off packets to send data to the sink.
My work requires sending periodic validation packets to each 1-hop neighbor, asking for information and awaiting a response. To achieve this, I created two methods in the routing protocol to handle this process:
void AquaSimVBF::SendRequest(AquaSimAddress src, AquaSimAddress des, AquaSimAddress targetNode)
{
// Ptr<Packet> packet = Create<Packet>();
Ptr<Packet> packet = CreatePacket();
AquaSimPtTag ptTag;
ptTag.SetPacketType(AquaSimPtTag::PT_RQST); //I created this tag to distinguish from regular data
packet->AddPacketTag(ptTag);
AquaSimHeader ash;
VBHeader vbh;
ash.SetSAddr(src);
ash.SetDAddr(des);
ash.SetSize(packet->GetSize());
//packet->AddHeader(ash);
ash.SetUId (packet->GetUid ());
ash.SetTimeStamp(Simulator::Now());
vbh.SetMessType(AquaSimPtTag::PT_RQST);
vbh.SetSenderAddr(src);
vbh.SetForwardAddr(des);
vbh.SetTargetAddr(des);
vbh.SetPkNum(packet->GetUid());
vbh.SetScore(0);
vbh.SetEvaluatedNode(targetNode);
packet->AddHeader(vbh);
packet->AddHeader(ash);
MACprepare(packet);
double jitter = m_rand->GetValue(0.1, JITTER); // Add random jitter
// MACsend(packet, jitter); // Send packet
for (int i = 0; i < 10; i++) { // Send three copies for redundancy, I did this to test the cause of why not all pkts received
double jitter = m_rand->GetValue(0.1, JITTER);
Simulator::Schedule(Seconds(i * 1.0), &AquaSimVBF::MACsend, this, packet->Copy(), jitter);
}
m_sentREQPkCount++;
}
void AquaSimVBF::SendResponse(double Score, AquaSimAddress src, AquaSimAddress dis, AquaSimAddress targetNode)
{
// Ptr<Packet> packet = Create<Packet>();
Ptr<Packet> packet = CreatePacket();
AquaSimPtTag ptTag;
ptTag.SetPacketType(AquaSimPtTag::PT_RESP);
packet->AddPacketTag(ptTag);
AquaSimHeader ash;
VBHeader vbh;
ash.SetSAddr(src);
ash.SetDAddr(dis);
ash.SetTimeStamp(Simulator::Now());
ash.SetSize(packet->GetSize());
//packet->AddHeader(ash);
vbh.SetMessType(AquaSimPtTag::PT_RESP);
vbh.SetSenderAddr(src);
vbh.SetForwardAddr(dis);
vbh.SetTargetAddr(dis);
vbh.SetPkNum(packet->GetUid());
vbh.SetScore(Score);
vbh.SetEvaluatedNode(targetNode);
packet->AddHeader(vbh);
packet->AddHeader(ash);
MACprepare(packet);
double jitter = m_rand->GetValue(0.1, JITTER);
// MACsend(packet, jitter); // Send packet
for (int i = 0; i < 10; i++) { // Send three copies for redundancy
double jitter = m_rand->GetValue(0.1, JITTER);
Simulator::Schedule(Seconds(i * 1.0), &AquaSimVBF::MACsend, this, packet->Copy(), jitter);
}
m_sentRESPkCount++;
}
Both methods are called at certain times during the simulation. I have successfully sent the packets, but not all of them are received at their destinations. My question is how to properly trace and identify why some packets are not received, given that all nodes under test are within range. I suspect I may have missed something. I tried to check for collisions with no luck on basic tracing, I want to ensure that the destination setup is correct. Here is my modification of Recv in VBF:
bool
AquaSimVBF::Recv (Ptr<Packet> packet, const Address &dest, uint16_t protocolNumber)
{
NS_LOG_FUNCTION(this);
AquaSimHeader ash;
VBHeader vbh;
AquaSimPtTag ptag;
AquaSimPtTag ptTag;
packet->PeekHeader (ash);
packet->PeekPacketTag(ptTag);
uint16_t packetType = ptTag.GetPacketType();
if (packetType == AquaSimPtTag::PT__RQST) {
//std::cout << "Node " << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << " RECV: PT_RQST"<<" des: "<<ash.GetDAddr().GetAsInt()<<"\n";
if(AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt()!=ash.GetDAddr().GetAsInt())
{
// std::cout << "------>Not for me drop it. Node " << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << " RECV: PT_RQST\n";
packet = 0;
return false;
}
/* std::cout <<"Time "<<Simulator::Now().ToDouble(Time::S) <<" Node " << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << " RECV: PT_RQST"
<<" stamp "<<ash.GetTimeStamp().ToDouble(Time::S)<< " src: "<<ash.GetSAddr().GetAsInt()<<" des: "<<ash.GetDAddr().GetAsInt()
<<" PacketNum "<<ash.GetUId()<<"\n";*/
HandleRequest(packet);
m_recvREQPkCount++;
m_recvPkCount++;
m_pkCount++;
return true;
}
if (packetType == AquaSimPtTag::PT_RESP) {
std::cout << "Node " << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << " RECV: PT_RESP\n";
if(AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt()!=ash.GetDAddr().GetAsInt())
{
// std::cout << "------>Not for me drop it. Node " << AquaSimAddress::ConvertFrom(m_device->GetAddress()).GetAsInt() << " RECV: PT_RESP\n";
packet = 0;
return false;
}
HandleResponse(packet);
m_recvRESPkCount++;
m_recvPkCount++;
m_pkCount++;
return true;
}
Here is a part of the script where I set up the communication to the sink. It works properly, although not all packets are received, which is expected given the propagation delay:
PacketSocketAddress socket;
socket.SetAllDevices();
// std::cout<<"sink index "<<sink_index<<std::endl;
socket.SetPhysicalAddress(devices.Get(sink_index)->GetAddress());
socket.SetProtocol(0);
// When an application is started, the first packet transmission occurs after a delay equal to =m_packetSize/m_dataRate in my case 0.032
// when an application transitions into an off state in between packet transmissions,
//the remaining time until when the next transmission would have occurred is cached and is used when the application starts up again
OnOffHelper app("ns3::PacketSocketFactory", Address(socket));
app.SetAttribute("OnTime",
StringValue("ns3::ConstantRandomVariable[Constant=0.032]")); //send one pkt in second //0.032
app.SetAttribute("OffTime",
StringValue("ns3::ConstantRandomVariable[Constant=20.0]"));
app.SetAttribute("DataRate", DataRateValue(m_dataRate));
app.SetAttribute("PacketSize", UintegerValue(m_packetSize));
double delay = 0.1;
for (NodeContainer::Iterator i = SenderCon.Begin(); i != SenderCon.End();
i++) {
ApplicationContainer apps1 = app.Install(*i);
apps1.Start(Seconds(delay));
apps1.Stop(Seconds(simStop));
delay += 0.1;
}