PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
ethernetPacketBackendLinux.cpp
Go to the documentation of this file.
1
3
4#include <unistd.h>
5
6#include <asio/posix/stream_descriptor.hpp>
7#include <cerrno>
8#include <cstring>
9
11#include "profinet/exceptions.h"
12
13namespace profinet
14{
16{
17 const int selectableFd =
18 pcap_get_selectable_fd(capture);
19
20 if (selectableFd < 0)
21 {
22 usePolling = true;
23 return;
24 }
25
26 const int duplicatedFd = ::dup(selectableFd);
27
28 if (duplicatedFd < 0)
29 {
30 throw SocketError("Failed to duplicate libpcap selectable descriptor: " + std::string(std::strerror(errno)));
31 }
32
33 asio::error_code error;
34
35 packetWait.assign(duplicatedFd, error);
36
37 if (error)
38 {
39 ::close(duplicatedFd);
40
41 throw SocketError("Failed to assign libpcap descriptor to Asio: " + error.message());
42 }
43
44 usePolling = false;
45}
46
47void AsioEthernetSocket::EthernetPacketBackend::AsyncWaitForPacket(const std::shared_ptr<ReceiveOperation>& operation)
48{
49 if (usePolling)
50 {
51 operation->pollTimer.expires_after(std::chrono::milliseconds(1));
52
53 operation->pollTimer.async_wait([this, operation](const asio::error_code& error)
54 {
55 HandlePacketReady(operation, error);
56 });
57
58 return;
59 }
60
61 packetWait.async_wait(asio::posix::stream_descriptor::wait_read, [this, operation](const asio::error_code& error)
62 {
63 HandlePacketReady(operation, error);
64 });
65}
66
67void AsioEthernetSocket::EthernetPacketBackend::CancelPacketWait(const std::shared_ptr<ReceiveOperation>& operation, asio::error_code& error)
68{
69 if (usePolling)
70 {
71 operation->pollTimer.cancel(error);
72 }
73 else
74 {
75 packetWait.cancel(error);
76 }
77}
78
79} // namespace profinet
void CancelPacketWait(const std::shared_ptr< ReceiveOperation > &operation, asio::error_code &error)
Cancel the current packet readiness operation.
bool usePolling
True when packet readiness must use timer polling.
void InitializePacketWait()
Connect the packet source to the Asio readiness mechanism.
asio::posix::stream_descriptor packetWait
Asio wrapper around the duplicated libpcap selectable descriptor.
void AsyncWaitForPacket(const std::shared_ptr< ReceiveOperation > &operation)
Start waiting until a packet source becomes readable.
Socket operation error.
Definition exceptions.h:663
Private Ethernet packet backend used by AsioEthernetSocket.
Declares exceptions and error types used by the PROFINET IO controller stack.
asio::error_code error