Skip to content

Commit

Permalink
Added npcap implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
FlorianReimold committed Apr 17, 2024
1 parent f83426d commit 4f6cc5c
Show file tree
Hide file tree
Showing 8 changed files with 361 additions and 2 deletions.
10 changes: 10 additions & 0 deletions samples/ecaludp_perftool/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,16 @@ set(sources
src/socket_builder_asio.cpp
src/socket_builder_asio.h
)
if (${ECALUDP_ENABLE_NPCAP})
list (APPEND sources
src/receiver_npcap_async.cpp
src/receiver_npcap_async.h
src/receiver_npcap_sync.cpp
src/receiver_npcap_sync.h
src/socket_builder_npcap.cpp
src/socket_builder_npcap.h
)
endif()

add_executable(${PROJECT_NAME} ${sources})

Expand Down
11 changes: 9 additions & 2 deletions samples/ecaludp_perftool/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@
#include "sender_async.h"
#include "sender_sync.h"

#if ECALUDP_UDPCAP_ENABLED
#include "receiver_npcap_sync.h"
#include "receiver_npcap_async.h"
#endif // ECALUDP_UDPCAP_ENABLED

#include "receiver_parameters.h"

enum class Implementation
{
NONE,
Expand Down Expand Up @@ -275,10 +282,10 @@ int main(int argc, char* argv[])
receiver = std::make_shared<ReceiverAsync>(receiver_parameters);
break;
case Implementation::RECEIVENPCAP:
std::cerr << "Error: Implementation not yet implemented" << std::endl; return 1;
receiver = std::make_shared<ReceiverNpcapSync>(receiver_parameters);
break;
case Implementation::RECEIVENPCAPASYNC:
std::cerr << "Error: Implementation not yet implemented" << std::endl; return 1;
receiver = std::make_shared<ReceiverNpcapAsync>(receiver_parameters);
break;
default:
break;
Expand Down
82 changes: 82 additions & 0 deletions samples/ecaludp_perftool/src/receiver_npcap_async.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#include "receiver_npcap_async.h"

#include <iostream>
#include <memory>
#include <mutex>
#include <thread>

#include <asio.hpp>

#include "ecaludp/socket.h"
#include "receiver.h"
#include "socket_builder_npcap.h"

ReceiverNpcapAsync::ReceiverNpcapAsync(const ReceiverParameters& parameters)
: Receiver(parameters)
{
std::cout << "Receiver implementation: Asynchronous NPCAP" << std::endl;
}

ReceiverNpcapAsync::~ReceiverNpcapAsync()
{
if (socket_)
{
socket_->close();
}
}

void ReceiverNpcapAsync::start()
{
try
{
socket_ = SocketBuilderNpcap::CreateReceiveSocket(parameters_);
}
catch (const std::exception& e)
{
std::cerr << "Error creating socket: " << e.what() << std::endl;
return; // TODO: Exit the app?
}

receive_message();
}

void ReceiverNpcapAsync::receive_message()
{
asio::ip::udp::endpoint endpoint;

socket_->async_receive_from(endpoint,
[this](const std::shared_ptr<ecaludp::OwningBuffer>& message, ecaludp::Error& error)
{
if (error)
{
std::cout << "Error sending: " << error.ToString() << std::endl;
socket_->close();
return;
}

{
std::unique_lock<std::mutex> lock(statistics_mutex_);

bytes_payload_ += message->size();
messages_received_ ++;
}

receive_message();
});
}
41 changes: 41 additions & 0 deletions samples/ecaludp_perftool/src/receiver_npcap_async.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#pragma once

#include "receiver.h"

#include <memory>
#include <thread>

#include <asio.hpp>

#include <ecaludp/socket_npcap.h>

class ReceiverNpcapAsync : public Receiver
{
public:
ReceiverNpcapAsync(const ReceiverParameters& parameters);
~ReceiverNpcapAsync() override;

void start() override;

private:
void receive_message();

private:
std::shared_ptr<ecaludp::SocketNpcap> socket_;
};
87 changes: 87 additions & 0 deletions samples/ecaludp_perftool/src/receiver_npcap_sync.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#include "receiver_npcap_sync.h"

#include <iostream>
#include <memory>
#include <mutex>
#include <thread>

#include <asio.hpp>

#include "ecaludp/socket_npcap.h"
#include "receiver.h"
#include "socket_builder_npcap.h"

ReceiverNpcapSync::ReceiverNpcapSync(const ReceiverParameters& parameters)
: Receiver(parameters)
{
std::cout << "Receiver implementation: Synchronous NPCAP" << std::endl;
}

ReceiverNpcapSync::~ReceiverNpcapSync()
{
if (receive_thread_ && receive_thread_->joinable())
{
receive_thread_->join();
}
}

void ReceiverNpcapSync::start()
{
receive_thread_ = std::make_unique<std::thread>(&ReceiverNpcapSync::receive_loop, this);
}

void ReceiverNpcapSync::receive_loop()
{
std::shared_ptr<ecaludp::SocketNpcap> receive_socket;
try
{
receive_socket = SocketBuilderNpcap::CreateReceiveSocket(parameters_);
}
catch (const std::exception& e)
{
std::cerr << "Error creating socket: " << e.what() << std::endl;
return; // TODO: Exit the app?
}

asio::ip::udp::endpoint destination(asio::ip::address::from_string(parameters_.ip), parameters_.port);

while (true)
{
{
ecaludp::Error error = ecaludp::Error::GENERIC_ERROR;
auto payload_buffer = receive_socket->receive_from(destination, error);

if (error)
{
std::cerr << "Error receiving message: " << error.ToString() << std::endl;
break;
}

{
std::unique_lock<std::mutex> lock(statistics_mutex_);

if (is_stopped_)
break;

bytes_payload_ += payload_buffer->size();
messages_received_ ++;
}
}
}
}
37 changes: 37 additions & 0 deletions samples/ecaludp_perftool/src/receiver_npcap_sync.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#pragma once

#include "receiver.h"

#include <memory>
#include <thread>

class ReceiverNpcapSync : public Receiver
{
public:
ReceiverNpcapSync(const ReceiverParameters& parameters);
~ReceiverNpcapSync() override;

void start() override;

private:
void receive_loop();

private:
std::unique_ptr<std::thread> receive_thread_;
};
67 changes: 67 additions & 0 deletions samples/ecaludp_perftool/src/socket_builder_npcap.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#include "socket_builder_npcap.h"

#include <memory>
#include <array>
#include <stdexcept>

#include <asio.hpp>
#include <ecaludp/socket_npcap.h>

#include "receiver_parameters.h"

namespace SocketBuilderNpcap
{
std::shared_ptr<ecaludp::SocketNpcap> CreateReceiveSocket(const ReceiverParameters& parameters)
{
auto socket = std::make_shared<ecaludp::SocketNpcap>(std::array<char, 4>{'E', 'C', 'A', 'L'});

asio::ip::address ip_address {};
{
asio::error_code ec;
ip_address = asio::ip::make_address(parameters.ip, ec);
if (ec)
{
throw std::runtime_error("Invalid IP address: " + parameters.ip);
}
}

// Set receive buffer size
if (parameters.buffer_size > 0)
{
asio::socket_base::receive_buffer_size option(parameters.buffer_size);
bool success = socket->set_receive_buffer_size(parameters.buffer_size);
if (!success)
{
throw std::runtime_error("Failed to set receive buffer size");
}
}

asio::ip::udp::endpoint destination(ip_address, parameters.port);

{
bool success = socket->bind(asio::ip::udp::endpoint(asio::ip::address_v4::loopback(), 14000));
if (!success)
{
throw std::runtime_error("Failed to bind socket");
}
}

return socket;
}
}
28 changes: 28 additions & 0 deletions samples/ecaludp_perftool/src/socket_builder_npcap.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/********************************************************************************
* Copyright (c) 2024 Continental Corporation
*
* This program and the accompanying materials are made available under the
* terms of the Apache License, Version 2.0 which is available at
* https://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* SPDX-License-Identifier: Apache-2.0
********************************************************************************/

#pragma once

#include <memory>

#include <ecaludp/socket_npcap.h>

#include "receiver_parameters.h"

namespace SocketBuilderNpcap
{
std::shared_ptr<ecaludp::SocketNpcap> CreateReceiveSocket(const ReceiverParameters& parameters);
}

0 comments on commit 4f6cc5c

Please sign in to comment.