From 40b8f992012604b18efca3a38656b20398e7b314 Mon Sep 17 00:00:00 2001 From: Michael Zillgith Date: Sat, 29 May 2021 13:14:41 +0200 Subject: [PATCH] - Ethernet Socket (Windows): fixed bug and added workaround for problem on Windows (most GOOSE/SV messages are not received when waiting with WaitForMultipleObjects - observed with winpcap 4.1.3 and Windows 10 --- hal/ethernet/win32/ethernet_win32.c | 24 ++++++++++++++++++++++-- src/sampled_values/sv_subscriber.c | 6 +++++- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/hal/ethernet/win32/ethernet_win32.c b/hal/ethernet/win32/ethernet_win32.c index d2a1f2f5..c6269f37 100644 --- a/hal/ethernet/win32/ethernet_win32.c +++ b/hal/ethernet/win32/ethernet_win32.c @@ -33,6 +33,9 @@ #define DEBUG_HAL_ETHERNET 1 #endif +// Set to 1 to workaround WaitForMutlipleObjects problem (returns timeout even when packets are received) +#define ETHERNET_WIN32_DISABLE_ETHERNET_HANDLESET 1 + #if (CONFIG_INCLUDE_ETHERNET_WINDOWS == 1) @@ -137,6 +140,8 @@ EthernetHandleSet_new(void) void EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock) { +#if ETHERNET_WIN32_DISABLE_ETHERNET_HANDLESET == 1 +#else if (self != NULL && sock != NULL) { int i = self->nhandles++; @@ -145,11 +150,14 @@ EthernetHandleSet_addSocket(EthernetHandleSet self, const EthernetSocket sock) self->handles[i] = pcap_getevent(sock->rawSocket); } +#endif } void EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock) { +#if ETHERNET_WIN32_DISABLE_ETHERNET_HANDLESET == 1 +#else if ((self != NULL) && (sock != NULL)) { HANDLE h = pcap_getevent(sock->rawSocket); @@ -163,21 +171,33 @@ EthernetHandleSet_removeSocket(EthernetHandleSet self, const EthernetSocket sock } } } +#endif } int EthernetHandleSet_waitReady(EthernetHandleSet self, unsigned int timeoutMs) { +#if ETHERNET_WIN32_DISABLE_ETHERNET_HANDLESET == 1 + return 1; +#else int result; if ((self != NULL) && (self->nhandles > 0)) { - result = WaitForMultipleObjects(self->nhandles, self->handles, 0, timeoutMs); + DWORD ret = WaitForMultipleObjects(self->nhandles, self->handles, 0, timeoutMs); + + if (ret == WAIT_TIMEOUT) + result = 0; + else if (ret == WAIT_FAILED) + result = -1; + else + result = (int)ret; } else { result = -1; } return result; +#endif } void @@ -328,7 +348,7 @@ Ethernet_createSocket(const char* interfaceId, uint8_t* destAddress) char* interfaceName = getInterfaceName(interfaceIndex); - if ((pcapSocket = pcap_open_live(interfaceName, 65536, PCAP_OPENFLAG_PROMISCUOUS, 10, errbuf)) == NULL) + if ((pcapSocket = pcap_open_live(interfaceName, 65536, PCAP_OPENFLAG_PROMISCUOUS, 1, errbuf)) == NULL) { printf("Open ethernet socket failed for device %s\n", interfaceName); free(interfaceName); diff --git a/src/sampled_values/sv_subscriber.c b/src/sampled_values/sv_subscriber.c index f37b3fbc..ee0e25a2 100644 --- a/src/sampled_values/sv_subscriber.c +++ b/src/sampled_values/sv_subscriber.c @@ -21,6 +21,7 @@ * See COPYING file for the complete license text. */ +#define __STDC_FORMAT_MACROS 1 #include "stack_config.h" #include @@ -356,9 +357,12 @@ parseASDU(SVReceiver self, SVSubscriber subscriber, uint8_t* buffer, int length) if (SVSubscriber_ASDU_hasDatSet(&asdu)) printf("SV_SUBSCRIBER: DatSet: %s\n", asdu.datSet); -#ifdef PRIu64 + if (SVSubscriber_ASDU_hasRefrTm(&asdu)) +#ifndef _MSC_VER printf("SV_SUBSCRIBER: RefrTm[ns]: %"PRIu64"\n", SVSubscriber_ASDU_getRefrTmAsNs(&asdu)); +#else + printf("SV_SUBSCRIBER: RefrTm[ns]: %llu\n", SVSubscriber_ASDU_getRefrTmAsNs(&asdu)); #endif if (SVSubscriber_ASDU_hasSmpMod(&asdu)) printf("SV_SUBSCRIBER: SmpMod: %d\n", SVSubscriber_ASDU_getSmpMod(&asdu));