To implement a smart city networking environment in ns-3 consists to simulating numerous types of network gadgets and applications that usually found in smart city. This contains interaction among IoT devices, traffic control systems, smart lighting and emergency response system. Here is the procedure on how to setup a general smart city network in ns3 environment:
Step-by-Step Implementation
- Install ns-3
Make sure ns-3 is installed on your system and can download it from official website.
- Define the Network Topology
The network topology that contains various nodes they are;
- Sensor nodes (e.g., temperature, pollution, and traffic sensors)
- Actuator nodes (e.g., smart lights and traffic signals)
- Control nodes (e.g., data aggregation points and control centers)
- Create Network Nodes
Create network nodes using NodeContainer.
NodeContainer sensorNodes, actuatorNodes, controlNodes;
sensorNodes.Create(10); // Create 10 sensor nodes
actuatorNodes.Create(5); // Create 5 actuator nodes
controlNodes.Create(2); // Create 2 control nodes
- Set Up Network Devices
Install network devices on the nodes using appropriate network interfaces, such as WiFi for wireless communication.
WifiHelper wifi;
wifi.SetStandard(WIFI_PHY_STANDARD_80211n_5GHZ);
WifiMacHelper mac;
mac.SetType(“ns3::AdhocWifiMac”);
YansWifiPhyHelper phy = YansWifiPhyHelper::Default();
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
phy.SetChannel(channel.Create());
NetDeviceContainer sensorDevices = wifi.Install(phy, mac, sensorNodes);
NetDeviceContainer actuatorDevices = wifi.Install(phy, mac, actuatorNodes);
NetDeviceContainer controlDevices = wifi.Install(phy, mac, controlNodes);
- Configure Mobility Model
Set up the mobility model for the nodes to simulate movement in the network.
MobilityHelper mobility;
mobility.SetMobilityModel(“ns3::ConstantPositionMobilityModel”);
mobility.Install(sensorNodes);
mobility.Install(actuatorNodes);
mobility.Install(controlNodes);
- Set Up Routing Protocols
Configure routing protocols for the network. A suitable routing protocol for smart city networks can be AODV, OLSR, or RPL.
AodvHelper aodv;
InternetStackHelper internet;
internet.SetRoutingHelper(aodv);
internet.Install(sensorNodes);
internet.Install(actuatorNodes);
internet.Install(controlNodes);
- Assign IP Addresses
Assign IP addresses to the network devices.
Ipv4AddressHelper address;
address.SetBase(“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer sensorInterfaces = address.Assign(sensorDevices);
Ipv4InterfaceContainer actuatorInterfaces = address.Assign(actuatorDevices);
Ipv4InterfaceContainer controlInterfaces = address.Assign(controlDevices);
- Implement Smart City Applications
Create applications that simulate smart city functionalities. Below is an example of a simple application that simulates sensor data collection and actuator control.
Sensor Application
class SensorApplication : public Application {
public:
void StartApplication() override {
sendSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
InetSocketAddress remote = InetSocketAddress(controlAddress, controlPort);
sendSocket->Connect(remote);
// Schedule the first data send
Simulator::Schedule(Seconds(1.0), &SensorApplication::SendSensorData, this);
}
void SetControlAddress(Ipv4Address address, uint16_t port) {
controlAddress = address;
controlPort = port;
}
void SendSensorData() {
std::ostringstream msg;
msg << “Sensor data from node ” << GetNode()->GetId();
Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.str().c_str(), msg.str().size());
sendSocket->Send(packet);
// Schedule the next data send
Simulator::Schedule(Seconds(10.0), &SensorApplication::SendSensorData, this);
}
private:
Ptr<Socket> sendSocket;
Ipv4Address controlAddress;
uint16_t controlPort;
};
Actuator Application
class ActuatorApplication : public Application {
public:
void StartApplication() override {
recvSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), localPort));
recvSocket->SetRecvCallback(MakeCallback(&ActuatorApplication::HandleRead, this));
}
void SetLocalPort(uint16_t port) {
localPort = port;
}
void HandleRead(Ptr<Socket> socket) {
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom(from))) {
std::cout << “Actuator node ” << GetNode()->GetId() << ” received control message.” << std::endl;
// Actuate based on the received message
}
}
private:
Ptr<Socket> recvSocket;
uint16_t localPort;
};
Control Application
class ControlApplication : public Application {
public:
void StartApplication() override {
recvSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), localPort));
recvSocket->SetRecvCallback(MakeCallback(&ControlApplication::HandleRead, this));
}
void SetLocalPort(uint16_t port) {
localPort = port;
}
void HandleRead(Ptr<Socket> socket) {
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom(from))) {
std::cout << “Control node ” << GetNode()->GetId() << ” received data.” << std::endl;
// Process sensor data and send control messages if needed
SendControlMessage();
}
}
void SendControlMessage() {
std::ostringstream msg;
msg << “Control message from node ” << GetNode()->GetId();
Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.str().c_str(), msg.str().size());
for (uint32_t i = 0; i < actuatorInterfaces.GetN(); ++i) {
sendSocket->SendTo(packet, 0, InetSocketAddress(actuatorInterfaces.GetAddress(i), actuatorPort));
}
}
void SetActuatorInterfaces(Ipv4InterfaceContainer interfaces, uint16_t port) {
actuatorInterfaces = interfaces;
actuatorPort = port;
}
private:
Ptr<Socket> recvSocket;
Ptr<Socket> sendSocket;
Ipv4InterfaceContainer actuatorInterfaces;
uint16_t localPort;
uint16_t actuatorPort;
};
- Install Applications
Install the applications on the nodes.
ApplicationContainer sensorApps, actuatorApps, controlApps;
// Install sensor applications
for (uint32_t i = 0; i < sensorNodes.GetN(); ++i) {
Ptr<SensorApplication> app = CreateObject<SensorApplication>();
app->SetControlAddress(controlNodes.Get(0)->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal(), 9);
sensorNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
sensorApps.Add(app);
}
// Install actuator applications
for (uint32_t i = 0; i < actuatorNodes.GetN(); ++i) {
Ptr<ActuatorApplication> app = CreateObject<ActuatorApplication>();
app->SetLocalPort(9);
actuatorNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
actuatorApps.Add(app);
}
// Install control applications
for (uint32_t i = 0; i < controlNodes.GetN(); ++i) {
Ptr<ControlApplication> app = CreateObject<ControlApplication>();
app->SetLocalPort(9);
app->SetActuatorInterfaces(actuatorInterfaces, 9);
controlNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
controlApps.Add(app);
}
- Run the Simulation
Configure the simulation runtime and execute it.
Simulator::Stop(Seconds(20.0));
Simulator::Run();
Simulator::Destroy();
Example of a Simple Smart City Network Script
Below is the sample script to complete the smartcity network simulation in ns-3 environment:
#include “ns3/core-module.h”
#include “ns3/network-module.h”
#include “ns3/internet-module.h”
#include “ns3/wifi-module.h”
#include “ns3/mobility-module.h”
#include “ns3/applications-module.h”
#include “ns3/aodv-module.h”
using namespace ns3;
class SensorApplication : public Application {
public:
void StartApplication() override {
sendSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
InetSocketAddress remote = InetSocketAddress(controlAddress, controlPort);
sendSocket->Connect(remote);
// Schedule the first data send
Simulator::Schedule(Seconds(1.0), &SensorApplication::SendSensorData, this);
}
void SetControlAddress(Ipv4Address address, uint16_t port) {
controlAddress = address;
controlPort = port;
}
void SendSensorData() {
std::ostringstream msg;
msg << “Sensor data from node ” << GetNode()->GetId();
Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.str().c_str(), msg.str().size());
sendSocket->Send(packet);
// Schedule the next data send
Simulator::Schedule(Seconds(10.0), &SensorApplication::SendSensorData, this);
}
private:
Ptr<Socket> sendSocket;
Ipv4Address controlAddress;
uint16_t controlPort;
};
class ActuatorApplication : public Application {
public:
void StartApplication() override {
recvSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), localPort));
recvSocket->SetRecvCallback(MakeCallback(&ActuatorApplication::HandleRead, this));
}
void SetLocalPort(uint16_t port) {
localPort = port;
}
void HandleRead(Ptr<Socket> socket) {
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom(from))) {
std::cout << “Actuator node ” << GetNode()->GetId() << ” received control message.” << std::endl;
// Actuate based on the received message
}
}
private:
Ptr<Socket> recvSocket;
uint16_t localPort;
};
class ControlApplication : public Application {
public:
void StartApplication() override {
recvSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
recvSocket->Bind(InetSocketAddress(Ipv4Address::GetAny(), localPort));
recvSocket->SetRecvCallback(MakeCallback(&ControlApplication::HandleRead, this));
sendSocket = Socket::CreateSocket(GetNode(), UdpSocketFactory::GetTypeId());
}
void SetLocalPort(uint16_t port) {
localPort = port;
}
void HandleRead(Ptr<Socket> socket) {
Ptr<Packet> packet;
Address from;
while ((packet = socket->RecvFrom(from))) {
std::cout << “Control node ” << GetNode()->GetId() << ” received data.” << std::endl;
// Process sensor data and send control messages if needed
SendControlMessage();
}
}
void SendControlMessage() {
std::ostringstream msg;
msg << “Control message from node ” << GetNode()->GetId();
Ptr<Packet> packet = Create<Packet>((uint8_t*) msg.str().c_str(), msg.str().size());
for (uint32_t i = 0; i < actuatorInterfaces.GetN(); ++i) {
sendSocket->SendTo(packet, 0, InetSocketAddress(actuatorInterfaces.GetAddress(i), actuatorPort));
}
}
void SetActuatorInterfaces(Ipv4InterfaceContainer interfaces, uint16_t port) {
actuatorInterfaces = interfaces;
actuatorPort = port;
}
private:
Ptr<Socket> recvSocket;
Ptr<Socket> sendSocket;
Ipv4InterfaceContainer actuatorInterfaces;
uint16_t localPort;
uint16_t actuatorPort;
};
int main(int argc, char *argv[]) {
NodeContainer sensorNodes, actuatorNodes, controlNodes;
sensorNodes.Create(10);
actuatorNodes.Create(5);
controlNodes.Create(2);
// WiFi setup
WifiHelper wifi;
wifi.SetStandard(WIFI_PHY_STANDARD_80211n_5GHZ);
WifiMacHelper mac;
mac.SetType(“ns3::AdhocWifiMac”);
YansWifiPhyHelper phy = YansWifiPhyHelper::Default();
YansWifiChannelHelper channel = YansWifiChannelHelper::Default();
phy.SetChannel(channel.Create());
NetDeviceContainer sensorDevices = wifi.Install(phy, mac, sensorNodes);
NetDeviceContainer actuatorDevices = wifi.Install(phy, mac, actuatorNodes);
NetDeviceContainer controlDevices = wifi.Install(phy, mac, controlNodes);
// Mobility setup
MobilityHelper mobility;
mobility.SetMobilityModel(“ns3::ConstantPositionMobilityModel”);
mobility.Install(sensorNodes);
mobility.Install(actuatorNodes);
mobility.Install(controlNodes);
// Internet stack and routing
AodvHelper aodv;
InternetStackHelper internet;
internet.SetRoutingHelper(aodv);
internet.Install(sensorNodes);
internet.Install(actuatorNodes);
internet.Install(controlNodes);
Ipv4AddressHelper address;
address.SetBase(“10.1.1.0”, “255.255.255.0”);
Ipv4InterfaceContainer sensorInterfaces = address.Assign(sensorDevices);
Ipv4InterfaceContainer actuatorInterfaces = address.Assign(actuatorDevices);
Ipv4InterfaceContainer controlInterfaces = address.Assign(controlDevices);
// Install applications
ApplicationContainer sensorApps, actuatorApps, controlApps;
// Install sensor applications
for (uint32_t i = 0; i < sensorNodes.GetN(); ++i) {
Ptr<SensorApplication> app = CreateObject<SensorApplication>();
app->SetControlAddress(controlNodes.Get(0)->GetObject<Ipv4>()->GetAddress(1, 0).GetLocal(), 9);
sensorNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
sensorApps.Add(app);
}
// Install actuator applications
for (uint32_t i = 0; i < actuatorNodes.GetN(); ++i) {
Ptr<ActuatorApplication> app = CreateObject<ActuatorApplication>();
app->SetLocalPort(9);
actuatorNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
actuatorApps.Add(app);
}
// Install control applications
for (uint32_t i = 0; i < controlNodes.GetN(); ++i) {
Ptr<ControlApplication> app = CreateObject<ControlApplication>();
app->SetLocalPort(9);
app->SetActuatorInterfaces(actuatorInterfaces, 9);
controlNodes.Get(i)->AddApplication(app);
app->SetStartTime(Seconds(1.0));
app->SetStopTime(Seconds(20.0));
controlApps.Add(app);
}
Simulator::Stop(Seconds(20.0));
Simulator::Run();
Simulator::Destroy();
return 0;
}
As we discussed earlier about how the Smart City network will perform in ns-3 environment and we help to provide further information about how the Smart City network will adapt in different environments. All types of Smart City network in ns-3 are worked by us where we guarantee best coding results.