i am just working on a realtime interface for the ns-3, therefore i just come up with a simple test manipulating DataRate and Delay of a CSMA-Example.
Therefore I used the first.cc example and edited it (below).
I just set up two threads and tried to manipulate the DataRate with the second thread after 4 seconds.
I also figured out that delay will be changed immediately but DataRate doesn´t.
I had to add one line into csma-net-device.cc function TransmitStart to update DataRate during the simulation as well.
So my problem now is, i don't know where the DataRate is stored exactly, can i just write some patch that every module can use or is there no "global" storepoint where my patch/interface can interact.
For this example/test i created, my question is: Is it right to interact like this or does someone know a better interacting method and is there any reason why datarate is not "updated/asked" during simulation.
Thanks for your help.
Bernhard.
/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation;
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <fstream>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/csma-helper.h"
#include <pthread.h>
#include <unistd.h>
using namespace ns3;
NS_LOG_COMPONENT_DEFINE ("FirstScriptExample");
void* runSim (void* p) {
Simulator::Stop(Seconds(15));
Simulator::Run();
return NULL;
}
NetDeviceContainer* handle = NULL;
void* inject (void* p) {
sleep (4);
handle->Get(0)->GetChannel()->SetAttribute("Delay", TimeValue (Seconds (0.5)));
handle->Get(0)->GetChannel()->SetAttribute("DataRate", StringValue("2Mbps"));
std::cout << "Changed." << std::endl;
return NULL;
}
int
main (int argc, char *argv[])
{
GlobalValue::Bind ("SimulatorImplementationType",
StringValue ("ns3::RealtimeSimulatorImpl"));
Time::SetResolution (Time::NS);
LogComponentEnable ("UdpEchoClientApplication", LOG_LEVEL_INFO);
LogComponentEnable ("UdpEchoServerApplication", LOG_LEVEL_INFO);
NodeContainer nodes;
nodes.Create (2);
CsmaHelper csma;
csma.SetChannelAttribute ("DataRate", StringValue("5Mbps"));
csma.SetChannelAttribute ("Delay", TimeValue (MilliSeconds (2)));
csma.SetDeviceAttribute ("Mtu", UintegerValue (1400));
NetDeviceContainer devices;
devices = csma.Install (nodes);
handle = &devices;
InternetStackHelper stack;
stack.Install (nodes);
Ipv4AddressHelper address;
address.SetBase ("10.1.1.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign (devices);
UdpEchoServerHelper echoServer (9);
ApplicationContainer serverApps = echoServer.Install (nodes.Get (1));
serverApps.Start (Seconds (1.0));
serverApps.Stop (Seconds (10.0));
UdpEchoClientHelper echoClient (interfaces.GetAddress (1), 9);
echoClient.SetAttribute ("MaxPackets", UintegerValue (1024));
echoClient.SetAttribute ("Interval", TimeValue (Seconds (1.0)));
echoClient.SetAttribute ("PacketSize", UintegerValue (1024));
ApplicationContainer clientApps = echoClient.Install (nodes.Get (0));
clientApps.Start (Seconds (2.0));
clientApps.Stop (Seconds (10.0));
pthread_t p, injector;
if (pthread_create (&p, NULL, runSim, NULL )){
std::cout << "Error" << std::endl;
return -1;
}
if (pthread_create (&injector, NULL, inject, NULL)){
std::cout << "Error" << std::endl;
return -1;
}
pthread_join(injector, NULL);
pthread_join(p, NULL);
std::cout << "joined thread" << std::endl;
Simulator::Destroy ();
std::cout << "simulator destroyed" << std::endl;
return 0;
}