Reputation: 11
I am using lena-simple-epc.cc as sample code, and I am trying to replace the default application with a specific custom application. My end goal is to transmit a single packet from one Ue to another Ue. I removed the section that includes the PacketSinkHelper and UDPClientHelp in the code and replaced it with:
for (uint32_t n = 0; n < ueNodes.GetN(); n++)
{
Ptr<ns3::Socket> srcSkt = Socket::CreateSocket(ueNodes.Get(n), TypeId::LookupByName ("ns3::UdpSocketFactory"));
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), 20000);
srcSkt->Bind (local);
srcSkt->SetRecvCallback (MakeCallback (&ReceivePacket));
}
uint16_t sinkPort = 20000;
Address sinkAddress (InetSocketAddress (ueIpIface.GetAddress (1), sinkPort));
Ptr<Socket> ns3UdpSocket = Socket::CreateSocket (ueNodes.Get(1), UdpSocketFactory::GetTypeId ());
ns3UdpSocket->Bind();
ns3UdpSocket->Connect(sinkAddress);
Ptr<Packet> packet = Create<Packet> (reinterpret_cast<const uint8_t*> ("Packet Via (LTE simulating Safety)"), 39);
ns3UdpSocket->Send(packet);
For the Receive Callback I have:
void ReceivePacket (Ptr<Socket> socket){
Ptr<Packet> packet;
uint32_t nodeIdr=socket->GetNode()->GetId();
while ((packet = socket->Recv ()))
{
uint8_t buf[1300];
packet->CopyData(buf , packet->GetSize());
std::cout<<"Data, "<<buf<< ", SimulatorTime, "<<Simulator::Now().GetSeconds()<<" NodeIDR "<<nodeIdr<<std::endl;
}}
When I do this, the receive callback is called, but it seems to be a loopback transmission. If I change the ueNode.Get() the program SIGSEGV:
Ptr<Socket> ns3UdpSocket = Socket::CreateSocket (ueNodes.Get(**0**), UdpSocketFactory::GetTypeId ());
Can anyone tell me what I may be doing wrong and what would be needed to send a custom packet from one ue to another?
Thank you ahead of time and my apologies on the formatting. First time posting.
Upvotes: 0
Views: 669
Reputation: 11
For anyone interested: I looked at the udp-client.cc file and noticed that the ->SetAllowBroadcast is set to true. Additionally, it seems to require to be run as a scheduled event. This got rid of the error and is now working. Here is the updated working code for customize packet based on content.
uint16_t otherPort = 3000;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<ns3::Socket> srcSkt = Socket::CreateSocket(ueNodes.Get(u), tid);
InetSocketAddress local = InetSocketAddress (Ipv4Address::GetAny (), otherPort);
srcSkt->Bind (local);
srcSkt->SetRecvCallback (MakeCallback (&ReceivePacket));
if (u+1 < ueNodes.GetN ())
{
Ptr<Socket> ns3UdpSocket = Socket::CreateSocket (ueNodes.Get(u), tid);
Ptr<Packet> pkt = Create<Packet> (reinterpret_cast<const uint8_t*> ("Packet Via (LTE simulating Safety)"), 39);
InetSocketAddress remote = InetSocketAddress (ueIpIface.GetAddress(u+1), otherPort);
ns3UdpSocket->Bind(remote);
ns3UdpSocket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
ns3UdpSocket->SetAllowBroadcast (true);
ns3UdpSocket->Connect (remote);
nodeInfo[u].sendSocketLTE=ns3UdpSocket;
nodeInfo[u].sendSocketLTE=ns3UdpSocket;
}
else
{
Ptr<Socket> ns3UdpSocket = Socket::CreateSocket (ueNodes.Get(u), tid);
Ptr<Packet> pkt = Create<Packet> (reinterpret_cast<const uint8_t*> ("Packet Via (LTE simulating Safety)"), 39);
InetSocketAddress remote = InetSocketAddress (ueIpIface.GetAddress(u-1), otherPort);
ns3UdpSocket->Bind(remote);
ns3UdpSocket->SetRecvCallback (MakeNullCallback<void, Ptr<Socket> > ());
ns3UdpSocket->SetAllowBroadcast (true);
ns3UdpSocket->Connect (remote);
nodeInfo[u].sendSocketLTE=ns3UdpSocket;
}
}
I created a struct to store the sockets in and simply call it when I need to send a packet nodeInfo[x].ns3UdpSocket->send(packet). Good Luck.
Upvotes: 1