Skip to content

Commit

Permalink
feat(daisi): Add TCP example application
Browse files Browse the repository at this point in the history
  • Loading branch information
ltoenning committed Sep 28, 2023
1 parent 8213b68 commit 4377a47
Show file tree
Hide file tree
Showing 4 changed files with 177 additions and 0 deletions.
5 changes: 5 additions & 0 deletions daisi/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ cmake_policy(VERSION 3.19)
include(CMakeDependentOption)

option(DAISI_DISABLE_NETWORK_SIMULATION "Disable ns-3 network simulation (use ns-3 as discrete event simulator only)" OFF)
option(DAISI_ENABLE_EXAMPLES "Enable DAISI ns-3 example applications" ON)
option(DAISI_ENABLE_COMPILER_WARNINGS "Build with compiler warnings" ON)
cmake_dependent_option(DAISI_HANDLE_COMPILER_WARNINGS_AS_ERRORS "Handle compiler warnings as error" OFF DAISI_ENABLE_COMPILER_WARNINGS OFF)

Expand Down Expand Up @@ -59,6 +60,10 @@ add_subdirectory(../ ${CMAKE_CURRENT_BINARY_DIR}/sola_mono)

add_subdirectory(src)

if(DAISI_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif()

add_subdirectory(tests/unittests)

add_subdirectory(third_party)
1 change: 1 addition & 0 deletions daisi/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
add_subdirectory(tcp)
14 changes: 14 additions & 0 deletions daisi/examples/tcp/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
add_executable(daisi_tcp_example tcp_example.cpp)
target_link_libraries(daisi_tcp_example
PRIVATE
ns3::libcore
daisi_network_tcp_server
daisi_network_tcp_client
daisi_utils
daisi_socket_manager
ns3::libcsma
)
target_include_directories(daisi_tcp_example
PRIVATE
${DAISI_SOURCE_DIR}/src
)
157 changes: 157 additions & 0 deletions daisi/examples/tcp/tcp_example.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
// Copyright 2023 The SOLA authors
//
// This file is part of DAISI.
//
// DAISI is free software: you can redistribute it and/or modify it under the terms of the GNU
// General Public License as published by the Free Software Foundation; version 2.
//
// DAISI 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 DAISI. If not, see
// <https://www.gnu.org/licenses/>.
//
// SPDX-License-Identifier: GPL-2.0-only

#include <cassert>
#include <iostream>

#include "network_tcp/client.h"
#include "network_tcp/server.h"
#include "ns3/applications-module.h"
#include "ns3/core-module.h"
#include "ns3/csma-module.h"
#include "ns3/internet-module.h"
#include "ns3/network-module.h"
#include "utils/socket_manager.h"
#include "utils/sola_utils.h"

using namespace ns3;
using namespace daisi;

/// TCP Pong server
class Server : public Application {
public:
static TypeId GetTypeId() {
static TypeId tid = TypeId("Server").SetParent<Application>().AddConstructor<Server>();
return tid;
}

Server() = default;

~Server() override = default;

void StartApplication() override {
auto new_msg = [this](network_tcp::TcpSocketHandle handle, const std::string &msg) {
std::cout << "[SERVER] \"" << msg << "\" from handle " << handle << "\n";
tcp_->send(handle, "PONG");
};

auto connected = [](network_tcp::TcpSocketHandle handle, const std::string &ip, uint16_t port) {
std::cout << "[SERVER] New connection from " << ip << ":" << port << " WITH HANDLE " << handle
<< "\n";
};

auto disconnected = [](network_tcp::TcpSocketHandle /*handle*/) {};

tcp_ = std::make_unique<network_tcp::Server>(
network_tcp::ServerCallbacks{new_msg, connected, disconnected});
std::cout << "[SERVER] Started on " << tcp_->getIP() << ":" << tcp_->getPort() << "\n";
}

void StopApplication() override { tcp_.reset(); }

private:
std::unique_ptr<network_tcp::Server> tcp_;
};

/// TCP client
class Client : public Application {
public:
static TypeId GetTypeId() {
static TypeId tid = TypeId("Client").SetParent<Application>();
return tid;
}

explicit Client(network_tcp::Endpoint endpoint) : endpoint_(std::move(endpoint)) {}

~Client() override = default;

void StartApplication() override {
auto new_msg = [](const std::string & /*msg*/) {};
auto connected = []() {};
auto disconnected = []() {};

tcp_ = std::make_unique<network_tcp::Client>(
network_tcp::ClientCallbacks{new_msg, connected, disconnected}, endpoint_);
}

void StopApplication() override { tcp_.reset(); }

void sendData(const std::string &msg) { tcp_->send(msg); }

private:
network_tcp::Endpoint endpoint_;

std::unique_ptr<network_tcp::Client> tcp_;
};

#define SCHEDULE(number, function, type, seconds) \
ns3::Simulator::ScheduleWithContext( \
node_container.Get(number)->GetId(), Seconds(seconds), &type::function, \
node_container.Get(number)->GetApplication(0)->GetObject<type>());

#define SCHEDULE_WITH_ARG(number, function, type, seconds, arg) \
ns3::Simulator::ScheduleWithContext( \
node_container.Get(number)->GetId(), Seconds(seconds), &type::function, \
node_container.Get(number)->GetApplication(0)->GetObject<type>(), arg);

int main(int /*argc*/, char * /*argv*/[]) {
NodeContainer node_container;
node_container.Create(2);

CsmaHelper csma;
csma.SetChannelAttribute("DataRate", StringValue("10Gbps"));
csma.SetChannelAttribute("Delay", StringValue("1ms"));

NetDeviceContainer net_devices;
net_devices = csma.Install(node_container);
csma.EnablePcapAll("output");

InternetStackHelper stack;
stack.Install(node_container);

Ipv4AddressHelper address;
address.SetBase("10.0.0.0", "255.255.255.0");
Ipv4InterfaceContainer interfaces = address.Assign(net_devices);

// Start one server and N-1 clients
for (auto i = 0; i < node_container.GetN(); i++) {
// Register node for automatic ns-3 socket creation
std::vector<ns3::Ipv4Address> addresses = daisi::getAddressesForNode(node_container, i);
daisi::SocketManager::get().registerNode(addresses, node_container.Get(i), 2000);

if (i == 0) {
Ptr<Server> app = CreateObject<Server>();
app->SetStartTime(Seconds(i));
app->SetStopTime(Seconds(9));

node_container.Get(i)->AddApplication(app);
} else {
network_tcp::Endpoint a{"10.0.0.1", 2000}; // Server endpoint
Ptr<Client> app = CreateObject<Client>(a);
app->SetStartTime(Seconds(i));
app->SetStopTime(Seconds(10));
node_container.Get(i)->AddApplication(app);
}
}

SCHEDULE_WITH_ARG(1, sendData, Client, 2, "Hello");

Simulator::Stop(Seconds(20));
Simulator::Run();
Simulator::Destroy();

return 0;
}

0 comments on commit 4377a47

Please sign in to comment.