I'm new to ns3 and I'm trying to develop and simulate a wireless load balancer schema with a random algorithm using ns3. I'm using IEEE 802.11 standard for the simulation; Also, I'm using release 3.35 of ns3.
More precisely, I'm trying to implement:
[IEEE 802.11 links]
[Sender0] --| |--[Receiver0]
[Sender1] --| |--[Receiver1]
[Sender2] --|--(UDP)--> [Load Balancer] --(TCP)-->|--[Receiver2]
[Sender3] --| |--[Receiver3]
[Sender4] --| |--[Receiver4]
Senders use UDP in order to send their packets to the load balancer. The load balancer use TCP in order to send received packets to the receivers.
It's obvious that the load balancer should send each packet to just one of the receivers. random load balancing algorithm is used in this simulation (load balancer randomly chooses one of the receivers and send the received packet to that).
I should calculate the throughput and average end-to-end delay of the network.
Moreover, error rate of the receiver nodes is 0.0001 and bandwidth is 1Mbps.
I've developed the following code so far:
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/applications-module.h"
#include "ns3/wifi-module.h"
#include "ns3/mobility-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include "ns3/flow-monitor-module.h"
#include "ns3/random-variable-stream.h"
#include "ns3/command-line.h"
#include "ns3/config.h"
#include "ns3/uinteger.h"
#include "ns3/boolean.h"
#include "ns3/string.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/udp-echo-helper.h"
#include "ns3/yans-wifi-channel.h"
#include "ns3/constant-position-mobility-model.h"
#include "ns3/propagation-loss-model.h"
#include "ns3/propagation-delay-model.h"
#include "ns3/on-off-helper.h"
#include "ns3/flow-monitor-helper.h"
#include "ns3/ipv4-flow-classifier.h"
using namespace ns3;
// Run single 10 seconds experiment
void experiment(bool enableCtsRts, std::string wifiManager)
{
// 0. Enable or disable CTS/RTS
UintegerValue ctsThr = (enableCtsRts ? UintegerValue (100) : UintegerValue (2200));
Config::SetDefault ("ns3::WifiRemoteStationManager::RtsCtsThreshold", ctsThr);
// 1. Create left, right, and load balancer nodes
NodeContainer router_node;
router_node.Create (1);
NodeContainer left_nodes;
left_nodes.Create (5);
NodeContainer right_nodes;
right_nodes.Create (5);
// 2. Place nodes somehow, this is required by every wireless simulation
for (uint8_t i = 0; i < 5; ++i) {
left_nodes.Get (i)->AggregateObject (CreateObject<ConstantPositionMobilityModel> ());
}
router_node.Get (0)->AggregateObject (CreateObject<ConstantPositionMobilityModel> ());
for (uint8_t i = 0; i < 5; ++i) {
right_nodes.Get (i)->AggregateObject (CreateObject<ConstantPositionMobilityModel> ());
}
// 3. Create propagation loss matrix
Ptr<MatrixPropagationLossModel> lossModel = CreateObject<MatrixPropagationLossModel> ();
lossModel->SetDefaultLoss (60); // set default loss to 60 dB (no link)
lossModel->SetLoss (left_nodes.Get (0)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss l0 <-> r to 50 dB
lossModel->SetLoss (left_nodes.Get (1)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss l1 <-> r to 50 dB
lossModel->SetLoss (left_nodes.Get (2)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss l2 <-> r to 50 dB
lossModel->SetLoss (left_nodes.Get (3)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss l3 <-> r to 50 dB
lossModel->SetLoss (left_nodes.Get (4)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss 14 <-> r to 50 dB
lossModel->SetLoss (right_nodes.Get (0)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss r <-> r0 to 50 dB
lossModel->SetLoss (right_nodes.Get (1)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss r <-> r1 to 50 dB
lossModel->SetLoss (right_nodes.Get (2)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss r <-> r2 to 50 dB
lossModel->SetLoss (right_nodes.Get (3)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss r <-> r3 to 50 dB
lossModel->SetLoss (right_nodes.Get (4)->GetObject<MobilityModel> (), router_node.Get (0)->GetObject<MobilityModel> (), 50); // set symmetric loss r <-> r4 to 50 dB
// 4. Create & setup wifi channel
Ptr<YansWifiChannel> wifiChannel = CreateObject <YansWifiChannel> ();
wifiChannel->SetPropagationLossModel (lossModel);
wifiChannel->SetPropagationDelayModel (CreateObject <ConstantSpeedPropagationDelayModel> ());
// 5. Install wireless devices
WifiHelper wifi;
wifi.SetStandard (WIFI_STANDARD_80211b);
wifi.SetRemoteStationManager ("ns3::" + wifiManager + "WifiManager");
YansWifiPhyHelper wifiPhy;
wifiPhy.SetChannel (wifiChannel);
WifiMacHelper staWifiMac, apWifiMac;
staWifiMac.SetType ("ns3::StaWifiMac");
apWifiMac.SetType ("ns3::ApWifiMac");
NetDeviceContainer left_devices = wifi.Install (wifiPhy, staWifiMac, left_nodes);
NetDeviceContainer router_device = wifi.Install (wifiPhy, apWifiMac, router_node);
NetDeviceContainer right_devices = wifi.Install (wifiPhy, staWifiMac, right_nodes);
// 6. Install TCP/IP stack & assign IP addresses
InternetStackHelper internet;
internet.Install (left_nodes);
internet.Install (router_node);
internet.Install (right_nodes);
Ipv4AddressHelper ipv4_le, ipv4_ro, ipv4_ri;
// Ipv4Address
ipv4_le.SetBase ("10.0.0.0", "255.255.255.0");
ipv4_ro.SetBase ("10.0.1.0", "255.255.255.0");
ipv4_ri.SetBase ("10.0.2.0", "255.255.255.0");
Ipv4InterfaceContainer left_addresses = ipv4_le.Assign (left_devices);
Ipv4InterfaceContainer router_address = ipv4_ro.Assign (router_device);
Ipv4InterfaceContainer right_addresses = ipv4_ri.Assign (right_devices);
// Configure IPv4 address
Ipv4Address addr;
for(int i = 0 ; i < 5; i++)
{
addr = left_addresses.GetAddress(i);
std::cout << " Left Node " << i+1 << "\t "<< "IP Address "<< addr << std::endl;
}
for(int i = 0 ; i < 5; i++)
{
addr = right_addresses.GetAddress(i);
std::cout << " Right Node " << i+1 << "\t "<< "IP Address "<< addr << std::endl;
}
addr = router_address.GetAddress(0);
std::cout << "Internet Stack & IPv4 address configured.." << '\n';
// TODO
}
int main (int argc, char **argv)
{
std::string wifiManager ("Arf");
CommandLine cmd (__FILE__);
cmd.AddValue ("wifiManager", "Set wifi rate manager (Aarf, Aarfcd, Amrr, Arf, Cara, Ideal, Minstrel, Onoe, Rraa)", wifiManager);
cmd.Parse (argc, argv);
std::cout << "Hidden station experiment with RTS/CTS disabled:\n" << std::flush;
experiment (false, wifiManager);
std::cout << "------------------------------------------------\n";
std::cout << "Hidden station experiment with RTS/CTS enabled:\n";
experiment (true, wifiManager);
return 0;
}
But my main problem is that I can't configure my nodes as the problem description and simulate the load balancing algorithm and this is actually because of the lack of tutorials and sample codes like this problem. Could someone help me?
Related
I'm trying to create Modbus TCP server with QT libraries.
I have problem, because I can't find a way, to create correct response for request from Modbus Client.
As I understand it, after starting the application, the server listens for incoming messages all the time, but I can't find in documentation correct function to handle message (and how I will get information about new request, it is a signal?)
I checked in the sample application QT ModbusServer, but did not find a solution.
There is my code:
#include <QCoreApplication>
#include <QModbusTcpServer>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QModbusTcpServer* modbusDevice;
modbusDevice = new QModbusTcpServer();
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "127.0.0.1");
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);
QModbusDataUnitMap reg;
reg.insert(QModbusDataUnit::Coils, { QModbusDataUnit::Coils, 0, 10 });
reg.insert(QModbusDataUnit::DiscreteInputs, { QModbusDataUnit::DiscreteInputs, 0, 10 });
reg.insert(QModbusDataUnit::InputRegisters, { QModbusDataUnit::InputRegisters, 0, 10 });
reg.insert(QModbusDataUnit::HoldingRegisters, { QModbusDataUnit::HoldingRegisters, 0, 10 });
modbusDevice->setMap(reg);
if(!modbusDevice->setMap(reg))
{
qDebug() << "setMap error";
}
modbusDevice->connectDevice();
return a.exec();
}
My goal is to read message from client with new register value and change that value in my application.
As a client, I am using the Modbus TCP sample application from QT.
You must set the server address with modbusDevice->setServerAddress(1) before calling connectDevice()
The parameter is the server instance. You can have at most 255 instances per IP address
modbusDevice->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "127.0.0.1");
modbusDevice->setConnectionParameter(QModbusDevice::NetworkPortParameter, 502);
modbusDevice->setServerAddress(1);
Then you must connect to QModbusServer::dataWritten, which is emitted by the server when the client modifies an object in the tables.
Something like
QObject::connect(modbusDevice, &QModbusServer::dataWritten,
[&] (QModbusDataUnit::RegisterType table, int address, int size)
{
qDebug() << "onDataWritten: table: " << table
<< " | " << "address: " << address
<< " | " << "size: " << size
<< endl;
}
);
While doing network simulation using ns-3 for IEEE802.11, there is a pcap file generated. I am able to filter all the information regarding rts, cts and ack from that pcap file using WireShark. But I need to extract the same information using flow monitor module (from the XML file generated). But I couldn't find any way for that. Is it possible to get that info using flow monitor or not?
My code is similar to the file ns-allinone-3.31/ns-3.31/examples/wireless/wifi-tcp.cc but enabled rts/cts and added flow monitor.
#include "ns3/command-line.h"
#include "ns3/config.h"
#include "ns3/string.h"
#include "ns3/log.h"
#include "ns3/yans-wifi-helper.h"
#include "ns3/ssid.h"
#include "ns3/mobility-helper.h"
#include "ns3/on-off-helper.h"
#include "ns3/yans-wifi-channel.h"
#include "ns3/mobility-model.h"
#include "ns3/packet-sink.h"
#include "ns3/packet-sink-helper.h"
#include "ns3/tcp-westwood.h"
#include "ns3/internet-stack-helper.h"
#include "ns3/ipv4-address-helper.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/flow-monitor.h"
#include "ns3/flow-monitor-module.h"
NS_LOG_COMPONENT_DEFINE ("wifi-tcp");
using namespace ns3;
Ptr<PacketSink> sink; /* Pointer to the packet sink application */
uint64_t lastTotalRx = 0; /* The value of the last total received bytes */
void
CalculateThroughput ()
{
Time now = Simulator::Now (); /* Return the simulator's virtual time. */
double cur = (sink->GetTotalRx () - lastTotalRx) * (double) 8 / 1e5; /* Convert Application RX Packets to MBits. */
std::cout << now.GetSeconds () << "s: \t" << cur << " Mbit/s" << std::endl;
lastTotalRx = sink->GetTotalRx ();
Simulator::Schedule (MilliSeconds (100), &CalculateThroughput);
}
int
main (int argc, char *argv[])
{
uint32_t payloadSize = 1472; /* Transport layer payload size in bytes. */
std::string dataRate = "100Mbps"; /* Application layer datarate. */
std::string tcpVariant = "TcpNewReno"; /* TCP variant type. */
std::string phyRate = "HtMcs7"; /* Physical layer bitrate. */
double simulationTime = 10; /* Simulation time in seconds. */
bool pcapTracing = true; /* PCAP Tracing is enabled or not. */
/* Command line argument parser setup. */
CommandLine cmd (__FILE__);
cmd.AddValue ("payloadSize", "Payload size in bytes", payloadSize);
cmd.AddValue ("dataRate", "Application data ate", dataRate);
cmd.AddValue ("tcpVariant", "Transport protocol to use: TcpNewReno, "
"TcpHybla, TcpHighSpeed, TcpHtcp, TcpVegas, TcpScalable, TcpVeno, "
"TcpBic, TcpYeah, TcpIllinois, TcpWestwood, TcpWestwoodPlus, TcpLedbat ", tcpVariant);
cmd.AddValue ("phyRate", "Physical layer bitrate", phyRate);
cmd.AddValue ("simulationTime", "Simulation time in seconds", simulationTime);
cmd.AddValue ("pcap", "Enable/disable PCAP Tracing", pcapTracing);
cmd.Parse (argc, argv);
tcpVariant = std::string ("ns3::") + tcpVariant;
// Select TCP variant
if (tcpVariant.compare ("ns3::TcpWestwoodPlus") == 0)
{
// TcpWestwoodPlus is not an actual TypeId name; we need TcpWestwood here
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TcpWestwood::GetTypeId ()));
// the default protocol type in ns3::TcpWestwood is WESTWOOD
Config::SetDefault ("ns3::TcpWestwood::ProtocolType", EnumValue (TcpWestwood::WESTWOODPLUS));
}
else
{
TypeId tcpTid;
NS_ABORT_MSG_UNLESS (TypeId::LookupByNameFailSafe (tcpVariant, &tcpTid), "TypeId " << tcpVariant << " not found");
Config::SetDefault ("ns3::TcpL4Protocol::SocketType", TypeIdValue (TypeId::LookupByName (tcpVariant)));
}
/* Configure TCP Options */
std::string RtsCtsThreshold="256";
std::string FragmentationThreshold="1000";
Config::SetDefault("ns3::WifiRemoteStationManager::RtsCtsThreshold",StringValue(RtsCtsThreshold));
Config::SetDefault("ns3::WifiRemoteStationManager::FragmentationThreshold",StringValue(FragmentationThreshold));
Config::SetDefault ("ns3::TcpSocket::SegmentSize", UintegerValue (payloadSize));
WifiMacHelper wifiMac;
WifiHelper wifiHelper;
wifiHelper.SetStandard (WIFI_PHY_STANDARD_80211n_5GHZ);
/* Set up Legacy Channel */
YansWifiChannelHelper wifiChannel;
wifiChannel.SetPropagationDelay ("ns3::ConstantSpeedPropagationDelayModel");
wifiChannel.AddPropagationLoss ("ns3::FriisPropagationLossModel", "Frequency", DoubleValue (5e9));
/* Setup Physical Layer */
YansWifiPhyHelper wifiPhy = YansWifiPhyHelper::Default ();
wifiPhy.SetChannel (wifiChannel.Create ());
wifiPhy.SetErrorRateModel ("ns3::YansErrorRateModel");
wifiHelper.SetRemoteStationManager ("ns3::ConstantRateWifiManager",
"DataMode", StringValue (phyRate),
"ControlMode", StringValue ("HtMcs0"));
NodeContainer networkNodes;
networkNodes.Create (2);
Ptr<Node> apWifiNode = networkNodes.Get (0);
Ptr<Node> staWifiNode = networkNodes.Get (1);
/* Configure AP */
Ssid ssid = Ssid ("network");
wifiMac.SetType ("ns3::ApWifiMac",
"Ssid", SsidValue (ssid));
NetDeviceContainer apDevice;
apDevice = wifiHelper.Install (wifiPhy, wifiMac, apWifiNode);
/* Configure STA */
wifiMac.SetType ("ns3::StaWifiMac",
"Ssid", SsidValue (ssid));
NetDeviceContainer staDevices;
staDevices = wifiHelper.Install (wifiPhy, wifiMac, staWifiNode);
/* Mobility model */
MobilityHelper mobility;
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
positionAlloc->Add (Vector (0.0, 0.0, 0.0));
positionAlloc->Add (Vector (1.0, 1.0, 0.0));
mobility.SetPositionAllocator (positionAlloc);
mobility.SetMobilityModel ("ns3::ConstantPositionMobilityModel");
mobility.Install (apWifiNode);
mobility.Install (staWifiNode);
/* Internet stack */
InternetStackHelper stack;
stack.Install (networkNodes);
Ipv4AddressHelper address;
address.SetBase ("10.0.0.0", "255.255.255.0");
Ipv4InterfaceContainer apInterface;
apInterface = address.Assign (apDevice);
Ipv4InterfaceContainer staInterface;
staInterface = address.Assign (staDevices);
/* Populate routing table */
Ipv4GlobalRoutingHelper::PopulateRoutingTables ();
/* Install TCP Receiver on the access point */
PacketSinkHelper sinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), 9));
ApplicationContainer sinkApp = sinkHelper.Install (apWifiNode);
sink = StaticCast<PacketSink> (sinkApp.Get (0));
/* Install TCP/UDP Transmitter on the station */
OnOffHelper server ("ns3::TcpSocketFactory", (InetSocketAddress (apInterface.GetAddress (0), 9)));
server.SetAttribute ("PacketSize", UintegerValue (payloadSize));
server.SetAttribute ("OnTime", StringValue ("ns3::ConstantRandomVariable[Constant=1]"));
server.SetAttribute ("OffTime", StringValue ("ns3::ConstantRandomVariable[Constant=0]"));
server.SetAttribute ("DataRate", DataRateValue (DataRate (dataRate)));
ApplicationContainer serverApp = server.Install (staWifiNode);
// Flow monitor
Ptr<FlowMonitor> flowMonitor;
FlowMonitorHelper flowHelper;
flowMonitor = flowHelper.InstallAll();
/* Start Applications */
sinkApp.Start (Seconds (0.0));
serverApp.Start (Seconds (1.0));
Simulator::Schedule (Seconds (1.1), &CalculateThroughput);
/* Enable Traces */
if (pcapTracing)
{
wifiPhy.SetPcapDataLinkType (WifiPhyHelper::DLT_IEEE802_11_RADIO);
wifiPhy.EnablePcap ("AccessPoint", apDevice);
wifiPhy.EnablePcap ("Station", staDevices);
}
/* Start Simulation */
Simulator::Stop (Seconds (simulationTime + 1));
Simulator::Run ();
flowMonitor->SerializeToXmlFile("1.xml", true, true);
double averageThroughput = ((sink->GetTotalRx () * 8) / (1e6 * simulationTime));
Simulator::Destroy ();
if (averageThroughput < 50)
{
NS_LOG_ERROR ("Obtained throughput is not in the expected boundaries!");
exit (1);
}
std::cout << "\nAverage throughput: " << averageThroughput << " Mbit/s" << std::endl;
return 0;
}
Thanks in advance :)
802.11 pcaps that include control frames (rts/cts/ack) are link layer.
Flow monitor is meant for transport layer, so you can't really get that data with it.
You can use wireshark/tshark to extract the data you want from the pcaps. Or maybe try pyshark to do it from a python script.
Following is the code i have written in ns3 for sending files using TCP. i have use mobility model and packetsinkhelper class along with bulksendHelper lass. Following Code is successfully build and created trace file but generated trace files shows empty.
#include "ns3/lte-helper.h"
#include "ns3/epc-helper.h"
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/ipv4-global-routing-helper.h"
#include "ns3/internet-module.h"
#include "ns3/mobility-module.h"
#include "ns3/lte-module.h"
#include "ns3/applications-module.h"
#include "ns3/point-to-point-helper.h"
#include "ns3/config-store.h"
#include "ns3/packet-sink.h"
//#include "ns3/gtk-config-store.h"
using namespace ns3;
/**
* Sample simulation script for LTE+EPC. It instantiates several eNodeB,
* attaches one UE per eNodeB starts a flow for each UE to and from a remote host.
* It also starts yet another flow between each UE pair.
*/
int
main (int argc, char *argv[])
{
uint16_t numberOfNodes = 10;
double simTime = 1.1;
double distance = 60.0;
uint32_t maxBytes = 0;
// Command line arguments
CommandLine cmd;
cmd.AddValue("numberOfNodes", "Number of eNodeBs + UE pairs", numberOfNodes);
cmd.AddValue("simTime", "Total duration of the simulation [s])", simTime);
cmd.AddValue("distance", "Distance between eNBs [m]", distance);
cmd.AddValue ("maxBytes","Total number of bytes for application to send", maxBytes);
cmd.Parse(argc, argv);
Ptr<LteHelper> lteHelper = CreateObject<LteHelper> ();
Ptr<PointToPointEpcHelper> epcHelper = CreateObject<PointToPointEpcHelper> ();
lteHelper->SetEpcHelper (epcHelper);
ConfigStore inputConfig;
inputConfig.ConfigureDefaults();
// parse again so you can override default values from the command line
cmd.Parse(argc, argv);
Ptr<Node> pgw = epcHelper->GetPgwNode ();
// Create a single RemoteHost
NodeContainer remoteHostContainer;
remoteHostContainer.Create (1);
Ptr<Node> remoteHost = remoteHostContainer.Get (0);
InternetStackHelper internet;
internet.Install (remoteHostContainer);
// Create the Internet
PointToPointHelper p2ph;
p2ph.SetDeviceAttribute ("DataRate", DataRateValue (DataRate ("100Gb/s")));
p2ph.SetDeviceAttribute ("Mtu", UintegerValue (1500));
p2ph.SetChannelAttribute ("Delay", TimeValue (Seconds (0.010)));
NetDeviceContainer internetDevices = p2ph.Install (pgw, remoteHost);
Ipv4AddressHelper ipv4h;
ipv4h.SetBase ("1.0.0.0", "255.0.0.0");
Ipv4InterfaceContainer internetIpIfaces = ipv4h.Assign (internetDevices);
// interface 0 is localhost, 1 is the p2p device
Ipv4Address remoteHostAddr = internetIpIfaces.GetAddress (1);
Ipv4StaticRoutingHelper ipv4RoutingHelper;
Ptr<Ipv4StaticRouting> remoteHostStaticRouting = ipv4RoutingHelper.GetStaticRouting (remoteHost->GetObject<Ipv4> ());
remoteHostStaticRouting->AddNetworkRouteTo (Ipv4Address ("7.0.0.0"), Ipv4Mask ("255.0.0.0"), 1);
NodeContainer ueNodes;
NodeContainer enbNodes;
enbNodes.Create(numberOfNodes);
ueNodes.Create(numberOfNodes);
// Install Mobility Model
Ptr<ListPositionAllocator> positionAlloc = CreateObject<ListPositionAllocator> ();
for (uint16_t i = 0; i < numberOfNodes; i++)
{
positionAlloc->Add (Vector(distance * i, 0, 0));
}
MobilityHelper mobility;
mobility.SetMobilityModel("ns3::ConstantPositionMobilityModel");
mobility.SetPositionAllocator(positionAlloc);
mobility.Install(enbNodes);
mobility.Install(ueNodes);
// Install LTE Devices to the nodes
NetDeviceContainer enbLteDevs = lteHelper->InstallEnbDevice (enbNodes);
NetDeviceContainer ueLteDevs = lteHelper->InstallUeDevice (ueNodes);
// Install the IP stack on the UEs
internet.Install (ueNodes);
Ipv4InterfaceContainer ueIpIface;
ueIpIface = epcHelper->AssignUeIpv4Address (NetDeviceContainer (ueLteDevs));
// Assign IP address to UEs, and install applications
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
Ptr<Node> ueNode = ueNodes.Get (u);
// Set the default gateway for the UE
Ptr<Ipv4StaticRouting> ueStaticRouting = ipv4RoutingHelper.GetStaticRouting (ueNode->GetObject<Ipv4> ());
ueStaticRouting->SetDefaultRoute (epcHelper->GetUeDefaultGatewayAddress (), 1);
}
// Attach one UE per eNodeB
for (uint16_t i = 0; i < numberOfNodes; i++)
{
lteHelper->Attach (ueLteDevs.Get(i), enbLteDevs.Get(i));
// side effect: the default EPS bearer will be activated
}
// Install and start applications on UEs and remote host
uint16_t dlPort = 1234;
uint16_t ulPort = 2000;
uint16_t otherPort = 3000;
ApplicationContainer clientApps;
ApplicationContainer serverApps;
for (uint32_t u = 0; u < ueNodes.GetN (); ++u)
{
++ulPort;
++otherPort;
PacketSinkHelper dlPacketSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), dlPort));
PacketSinkHelper ulPacketSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), ulPort));
PacketSinkHelper packetSinkHelper ("ns3::TcpSocketFactory", InetSocketAddress (Ipv4Address::GetAny (), otherPort));
serverApps.Add (dlPacketSinkHelper.Install (ueNodes.Get(u)));
serverApps.Add (ulPacketSinkHelper.Install (remoteHost));
serverApps.Add (packetSinkHelper.Install (ueNodes.Get(u)));
BulkSendHelper dlClient ("ns3::TcpSocketFactory", InetSocketAddress(ueIpIface.GetAddress (u), dlPort));
dlClient.SetAttribute ("MaxBytes", UintegerValue(maxBytes));
BulkSendHelper ulClient ("ns3::TcpSocketFactory",InetSocketAddress(remoteHostAddr, ulPort));
ulClient.SetAttribute ("MaxBytes", UintegerValue(maxBytes));
BulkSendHelper client ("ns3::TcpSocketFactory",InetSocketAddress(ueIpIface.GetAddress (u), otherPort));
client.SetAttribute ("MaxBytes", UintegerValue(maxBytes));
clientApps.Add (dlClient.Install (remoteHost));
clientApps.Add (ulClient.Install (ueNodes.Get(u)));
if (u+1 < ueNodes.GetN ())
{
clientApps.Add (client.Install (ueNodes.Get(u+1)));
}
else
{
clientApps.Add (client.Install (ueNodes.Get(0)));
}
}
serverApps.Start (Seconds (0.01));
clientApps.Start (Seconds (0.01));
serverApps.Stop (Seconds (10.0));
clientApps.Stop (Seconds (10.0));
lteHelper->EnableTraces ();
// Uncomment to enable PCAP tracing
//p2ph.EnablePcapAll("lena-epc-first");
Simulator::Stop(Seconds(simTime));
Simulator::Run();
/*GtkConfigStore config;
config.ConfigureAttributes();*/
Simulator::Destroy();
return 0;
}
Please look into above code and suggest if anything is missing to obtained output in trace file.
I have an Arudino Uno with an Adafruit CC3000 wifi shield attached.
I am trying to send multiple http requests and store the results from the GET requests. I can make and receive the requests successfully, but space on the arduino (in the buffer?) runs out when I try to store more than one of the responses.
I'm happy to store one string at a time so I figured that instead of using the arduino String class if I use a char array instead and allocate memory, I can then free the memory afterwards. That way I could use the memory as required, hopefully not cause any issues in running the rest of the code. I know this also depends on how long the incoming response is, but let's assume the response size is small enough. Feel free to shoot me down if there are flaws in my logic... (likely)
I tried variations of creating the char array without having to define the size beforehand and then using strcpy or strcat to append the new characters, but with no success.
I want to do something in the process of: create char array, fill it, use it, free it from memory.
In the past I've used this method in such a form:
char *array = new char[size_wanted];
strcpy(array,some_char_array);
strcat(array,some_other_char_array);
This of course works well when you know what size_wanted is. I don't until I read the buffer, but once I've read the buffer I've read it, so cannot read it again. Am I missing a trick here?! Is there a simpler way to do this using the Arduino String class? Am I missing the obvious or just not understanding how this works? Any ideas would be greatly appreciated.
My code:
/***************************************************
Adafruit CC3000 Wifi Breakout & Shield Example
****************************************************/
#include <Adafruit_CC3000.h>
#include <ccspi.h>
#include <SPI.h>
#include <string.h>
#include "utility/debug.h"
// These are the interrupt and control pins
#define ADAFRUIT_CC3000_IRQ 2 // MUST be an interrupt pin!
// These can be any two pins
#define ADAFRUIT_CC3000_VBAT 5
#define ADAFRUIT_CC3000_CS 10
// Use hardware SPI for the remaining pins
// On an UNO, SCK = 13, MISO = 12, and MOSI = 11
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
SPI_CLOCK_DIVIDER); // you can change this clock speed
#define WLAN_SSID "wifi"
#define WLAN_PASS "passoword"
#define WLAN_SECURITY WLAN_SEC_WPA2
#define IDLE_TIMEOUT_MS 3000
// What page to grab!
#define WEBSITE "www.adafruit.com"
#define WEBPAGE "/testwifi/index.html"
uint32_t ip;
int n = 1;
char* result;
void setup(void)
{
Serial.begin(115200);
Serial.println(F("Hello, CC3000!\n"));
Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
/* Initialise the module */
Serial.println(F("\nInitializing..."));
if (!cc3000.begin())
{
Serial.println(F("Couldn't begin()! Check your wiring?"));
while(1);
}
Serial.print(F("\nAttempting to connect to ")); Serial.println(WLAN_SSID);
if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
Serial.println(F("Failed!"));
while(1);
}
Serial.println(F("Connected!"));
/* Wait for DHCP to complete */
Serial.println(F("Request DHCP"));
while (!cc3000.checkDHCP())
{
delay(100); // ToDo: Insert a DHCP timeout!
}
/* Display the IP address DNS, Gateway, etc. */
while (! displayConnectionDetails()) {
delay(1000);
}
ip = 0;
// Try looking up the website's IP address
Serial.print(WEBSITE); Serial.print(F(" -> "));
while (ip == 0) {
if (! cc3000.getHostByName(WEBSITE, &ip)) {
Serial.println(F("Couldn't resolve!"));
}
delay(500);
}
cc3000.printIPdotsRev(ip);
String r1, r2, r3, r4, r5;
r1 = connect_to_webclient();
r2 = connect_to_webclient();
r3 = connect_to_webclient();
r4 = connect_to_webclient();
r5 = connect_to_webclient();
/*
Serial.println("RESULTS:");
Serial.println("r1:"); Serial.println(r1);
Serial.println("r2:"); Serial.println(r2);
Serial.println("r3:"); Serial.println(r3);
Serial.println("r4:"); Serial.println(r4);
Serial.println("r5:"); Serial.println(r5);
*/
/* You need to make sure to clean up after yourself or the CC3000 can freak out */
/* the next time your try to connect ... */
Serial.println(F("\n\nDisconnecting"));
cc3000.disconnect();
}
void loop(void)
{
delay(1000);
}
bool displayConnectionDetails(void)
{
uint32_t ipAddress, netmask, gateway, dhcpserv, dnsserv;
if(!cc3000.getIPAddress(&ipAddress, &netmask, &gateway, &dhcpserv, &dnsserv))
{
Serial.println(F("Unable to retrieve the IP Address!\r\n"));
return false;
}
else
{
Serial.print(F("\nIP Addr: ")); cc3000.printIPdotsRev(ipAddress);
Serial.print(F("\nNetmask: ")); cc3000.printIPdotsRev(netmask);
Serial.print(F("\nGateway: ")); cc3000.printIPdotsRev(gateway);
Serial.print(F("\nDHCPsrv: ")); cc3000.printIPdotsRev(dhcpserv);
Serial.print(F("\nDNSserv: ")); cc3000.printIPdotsRev(dnsserv);
Serial.println();
return true;
}
}
String connect_to_webclient() {
/* Try connecting to the website.
Note: HTTP/1.1 protocol is used to keep the server from closing the connection before all data is read.
*/
Serial.print("\nConnection number: ");
Serial.println(n);
Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
if (www.connected()) {
Serial.println("Connected succeeded");
www.fastrprint(F("GET "));
www.fastrprint(WEBPAGE);
www.fastrprint(F(" HTTP/1.1\r\n"));
www.fastrprint(F("Host: ")); www.fastrprint(WEBSITE); www.fastrprint(F("\r\n"));
www.fastrprint(F("\r\n"));
www.println();
} else {
Serial.println(F("Connection failed"));
return;
}
Serial.println(F("-------------------------------------"));
/* Read data until either the connection is closed, or the idle timeout is reached. */
unsigned long lastRead = millis();
while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
while (www.available()) {
char c = www.read();
Serial.print(c);
//strcat(result, c);
lastRead = millis();
}
}
www.close();
Serial.println(F("-------------------------------------"));
n++;
return result;
}
My goal is to create an ALU that adds and subtracts with a barrelshifter
alu.h
#include "systemc.h"
SC_MODULE(alu){
sc_in<bool> op;
sc_in<sc_int<8> > a;
sc_inout<sc_int<8> > b;
sc_out<sc_int<8> > output;
void alu_method();
SC_CTOR(alu) {
SC_METHOD(alu_method);
dont_initialize();
sensitive << a,b,op;
}
};
alu.cpp
#include "alu.h"
void ALU::alu_method(){
if (op.read() == 0){
//substract
out.write(in.read() - in_bs.read());
}
else{
//add
out.write(in.read() + in_bs.read());
}
}
barrelshift.h
#include <systemc.h>
void make_barrel();
SC_MODULE(barrel_shift) {
sc_in<bool> clk;
sc_in<bool> enable;
sc_in<bool> left_right;
sc_in<sc_uint<3> > shift_amt;
sc_in<sc_int<8> > din;
sc_inout<sc_int<8> > dout;
void barrel_method();
SC_CTOR(barrel_shift) {
SC_METHOD(barrel_method);
dont_initialize();
sensitive << clk.pos(); //edge sensitive
}
};
barrelshift.cpp
#include "barrelshift.h"
void barrel_shift :: barrel_method(){
if(enable.read() == 1){
if(left_right.read() == 0){ //shift left
dout.write(din.read() << shift_amt.read());
}else if(left_right.read() == 1){ // right shift
dout.write(din.read() >> shift_amt.read());
}
}
else
cout << "Not enabled "<<endl;
dout <= din;
}
sc_main.cpp
#include <systemc.h>
#include "alu.h"
#include "barrelshift.h"
int sc_main(int argc, char* argv[]){
sc_trace_file *tf;
//Signals
sc_signal <bool> enable, op, l_r;
sc_signal <sc_int<8> > a, output,b, bin;
sc_signal < sc_uint<3> > shift_amt;
//Clock
sc_clock clk("clk",10,SC_PS,0.5);
alu myALU("myALU");
barrel_shift myShifter("myShifter");
myALU.a(a);
myALU.b(b);
myALU.output(output);
myALU.op(op);
myShifter.clk(clk);
myShifter.din(bin);
myShifter.enable(enable);
myShifter.left_right(l_r);
myShifter.shift_amt(shift_amt);
myShifter.dout(b);
tf = sc_create_vcd_trace_file("trace_file");
sc_trace(tf, clk, "clk");
sc_trace(tf, a, "a");
sc_trace(tf, bin, "BarrelShifter In");
sc_trace(tf, op, "op");
sc_trace(tf, shift_amt, "shift_amt");
sc_trace(tf, l_r, "left_right");
sc_trace(tf, enable, "enable");
sc_trace(tf, b, "b");
sc_trace(tf, output, "output");
sc_close_vcd_trace_file(tf);
cout << "The result from the ALU is: " << output.read();
}
There are no errors when I build it. But whenever I try to execute it, I get the following error:
Error: (E112) get interface failed: port is not bound: port 'myALU.port_0' (sc_in)
In file: sc_port.cpp:231
What is causing this and how can I fix it?
The error message
Error: (E112) get interface failed: port is not bound: port 'myALU.port_0' (sc_in)
means that the port myALU.port_0 is not bound to a signal. But which port in the alu module corresponds to port_0?
It is good practice to name all ports and signals -- regardless of the type of hardware description language you are using -- to make errors like this easier to diagnose.
Name the ports in the alu constructor:
SC_CTOR(alu) :
op("op"),
a("a"),
b("b"),
output("output")
{
// ...
I couldn't reproduce the error you were seeing. I saw this error (after providing names for all ports and signals):
Error: (E115) sc_signal<T> cannot have more than one driver:
signal `signal_5' (sc_signal)
first driver `myShifter.dout' (sc_inout)
second driver `myALU.b' (sc_inout)
I noticed some other problems in your code:
Your code doesn't compile because the wrong variable names are used in alu_method().
sc_start() is not called in sc_main().
There is an invalid sensitive call in alu() -- should be sensitive << a << b << op;
The problem was with the sensitivity list for alu. It should have been:
sensitive << a << b << op;
As noted correctly by #DarrylLawson, this error message indicates that the the port myALU.port_0 is not bound to a signal (and you would get a clearer name if you had given the port a name in the constructor).
An important nuance imho is that it means the port is not bound to a signal at the time the error is given. You may have code that binds it, but this is only executed at some point during elaboration. If you try to use the port before that (e.g. inside the constructor of your module), you can still get this error message. In that case the error would occur at time 0.