PROFINET IO Controller Stack 1.0.0
Modern C++ implementation of a PROFINET IO Controller stack
Loading...
Searching...
No Matches
ethernetPacketBackendWindows.cpp
Go to the documentation of this file.
1
3
4#ifndef NOMINMAX
5#define NOMINMAX
6#endif
7#ifndef WIN32_LEAN_AND_MEAN
8#define WIN32_LEAN_AND_MEAN
9#endif
10#include <winsock2.h>
11#include <windows.h>
12
13#include <asio/windows/object_handle.hpp>
14
16#include "profinet/exceptions.h"
17
18namespace profinet
19{
21{
22 const HANDLE captureEvent = pcap_getevent(capture);
23
24 if (captureEvent == nullptr || captureEvent == INVALID_HANDLE_VALUE)
25 {
26 usePolling = true;
27 return;
28 }
29
30 HANDLE duplicatedEvent = nullptr;
31
32 if (!DuplicateHandle(GetCurrentProcess(), captureEvent, GetCurrentProcess(), &duplicatedEvent, 0, FALSE, DUPLICATE_SAME_ACCESS))
33 {
34 throw SocketError("Failed to duplicate libpcap packet event: error " + std::to_string(GetLastError()));
35 }
36
37 asio::error_code error;
38
39 packetWait.assign(duplicatedEvent, error);
40
41 if (error)
42 {
43 CloseHandle(duplicatedEvent);
44
45 throw SocketError("Failed to assign libpcap event to Asio: " + error.message());
46 }
47
48 usePolling = false;
49}
50
51void AsioEthernetSocket::EthernetPacketBackend::AsyncWaitForPacket(const std::shared_ptr<ReceiveOperation>& operation)
52{
53 if (usePolling)
54 {
55 operation->pollTimer.expires_after(std::chrono::milliseconds(1));
56
57 operation->pollTimer.async_wait([this, operation](const asio::error_code& error)
58 {
59 HandlePacketReady(operation, error);
60 });
61
62 return;
63 }
64
65 packetWait.async_wait([this, operation](const asio::error_code& error)
66 {
67 HandlePacketReady(operation, error);
68 });
69}
70
71void AsioEthernetSocket::EthernetPacketBackend::CancelPacketWait(const std::shared_ptr<ReceiveOperation>& operation, asio::error_code& error)
72{
73 if (usePolling)
74 {
75 operation->pollTimer.cancel(error);
76 }
77 else
78 {
79 packetWait.cancel(error);
80 }
81}
82
83} // 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.
Private Ethernet packet backend used by AsioEthernetSocket.
Declares exceptions and error types used by the PROFINET IO controller stack.
asio::error_code error