Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Melik Merkumians2017-08-18 08:53:04 +0000
committerMartin Melik Merkumians2017-08-18 09:09:34 +0000
commit93bbd5a61ece3373d9961ea7b04de900067baf2e (patch)
tree9f872c0134848a3c96e3a697cd5e62c51b3c565c
parent93ddd991cee767c539f27e85c416845abe01cdf8 (diff)
downloadorg.eclipse.4diac.forte-1.8.x.tar.gz
org.eclipse.4diac.forte-1.8.x.tar.xz
org.eclipse.4diac.forte-1.8.x.zip
[521105] Adds Win32 specific socket interface fixing error messages for Windows1.8.x
Bug: https://bugs.eclipse.org/bugs/show_bug.cgi?id=521105 Signed-off-by: Martin Melik Merkumians <melik-merkumians@acin.tuwien.ac.at>
-rw-r--r--src/arch/win32/CMakeLists.txt2
-rw-r--r--src/arch/win32/sockhand.h4
-rw-r--r--src/arch/win32/win32socketinterf.cpp266
-rw-r--r--src/arch/win32/win32socketinterf.h38
-rw-r--r--src/core/cominfra/ipcomlayer.cpp2
5 files changed, 308 insertions, 4 deletions
diff --git a/src/arch/win32/CMakeLists.txt b/src/arch/win32/CMakeLists.txt
index 7a2ab62cb..c7cc7be0c 100644
--- a/src/arch/win32/CMakeLists.txt
+++ b/src/arch/win32/CMakeLists.txt
@@ -36,7 +36,7 @@ if("${FORTE_ARCHITECTURE}" STREQUAL "Win32")
if(FORTE_COM_ETH)
- forte_add_sourcefile_hcpp( ../fdselecthand ../bsdsocketinterf)
+ forte_add_sourcefile_hcpp( ../fdselecthand win32socketinterf )
forte_add_sourcefile_h(../gensockhand.h)
forte_add_sourcefile_h(sockhand.h)
endif(FORTE_COM_ETH)
diff --git a/src/arch/win32/sockhand.h b/src/arch/win32/sockhand.h
index 7a49bb140..9a34a0845 100644
--- a/src/arch/win32/sockhand.h
+++ b/src/arch/win32/sockhand.h
@@ -24,9 +24,9 @@
#include <Ws2tcpip.h>
//these include needs to be last
#include "../fdselecthand.h"
-#include "../bsdsocketinterf.h"
+#include "win32socketinterf.h"
#include "../gensockhand.h"
-typedef CGenericIPComSocketHandler<CFDSelectHandler, CBSDSocketInterface> CIPComSocketHandler;
+typedef CGenericIPComSocketHandler<CFDSelectHandler, CWin32SocketInterface> CIPComSocketHandler;
#endif /* SOCKHAND_H_ */
diff --git a/src/arch/win32/win32socketinterf.cpp b/src/arch/win32/win32socketinterf.cpp
new file mode 100644
index 000000000..3ba1904c8
--- /dev/null
+++ b/src/arch/win32/win32socketinterf.cpp
@@ -0,0 +1,266 @@
+/*******************************************************************************
+ * Copyright (c) 2010 - 2015 ACIN, Profactor GmbH, AIT, fortiss GmbH
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alois Zoitl, Ingo Hegny, Gerhard Ebenhofer, Thomas Strasser
+ * - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+#include <sockhand.h> //needs to be first pulls in the platform specific includes
+#include <windows.h>
+#include <string.h>
+
+#include "win32socketinterf.h"
+
+#include "devlog.h"
+
+void CWin32SocketInterface::closeSocket(TSocketDescriptor pa_nSockD){
+ closesocket(pa_nSockD);
+}
+
+CWin32SocketInterface::TSocketDescriptor CWin32SocketInterface::openTCPServerConnection(char *pa_acIPAddr, unsigned short pa_nPort){
+ TSocketDescriptor nRetVal = INVALID_SOCKET;
+
+ DEVLOG_INFO("CWin32SocketInterface: Opening TCP-Server connection at: %s:%d\n", pa_acIPAddr, pa_nPort);
+
+ TSocketDescriptor nSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ if(INVALID_SOCKET != nSocket){
+ struct sockaddr_in stSockAddr = { 0 };
+ stSockAddr.sin_family = AF_INET;
+ stSockAddr.sin_port = htons(pa_nPort);
+ stSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+ int nOptVal = 1;
+ if(setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &nOptVal, sizeof(nOptVal)) == -1){
+ LPSTR pacErrorMessage = getErrorMessage(WSAGetLastError());
+ DEVLOG_ERROR("CWin32SocketInterface: could not set socket option SO_REUSEADDR: %s\n", pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+
+ if(0 == bind(nSocket, (struct sockaddr *) &stSockAddr, sizeof(struct sockaddr))){
+ if(-1 == listen(nSocket, 1)){ // for the classic IEC 61499 server only one connection at the same time is accepted TODO mayb make this adjustable for future extensions
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: listen() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ else{
+ nRetVal = nSocket;
+ }
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: bind() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: Couldn't create socket: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+CWin32SocketInterface::TSocketDescriptor CWin32SocketInterface::openTCPClientConnection(char *pa_acIPAddr, unsigned short pa_nPort){
+ TSocketDescriptor nRetVal = INVALID_SOCKET;
+ TSocketDescriptor nSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+
+ DEVLOG_INFO("CWin32SocketInterface: Opening TCP-Client connection at: %s:%d\n", pa_acIPAddr, pa_nPort);
+
+ if(-1 != nSocket){
+ struct sockaddr_in stSockAddr = { 0 };
+ stSockAddr.sin_family = AF_INET;
+ stSockAddr.sin_port = htons(pa_nPort);
+ if(1 != InetPton(stSockAddr.sin_family, pa_acIPAddr, &(stSockAddr.sin_addr))) {
+ DEVLOG_ERROR("CWin32SocketInterface: InetPton() failed: %d - %s\n", stSockAddr.sin_addr.s_addr, pa_acIPAddr);
+ }
+
+ if(-1 == connect(nSocket, (struct sockaddr *) &stSockAddr, sizeof(struct sockaddr))){
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: connect() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ else{
+ nRetVal = nSocket;
+ }
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: Couldn't create socket: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+CWin32SocketInterface::TSocketDescriptor CWin32SocketInterface::acceptTCPConnection(TSocketDescriptor pa_nListeningSockD){
+ struct sockaddr client_addr;
+ int sin_size = sizeof(struct sockaddr);
+ TSocketDescriptor nRetVal = INVALID_SOCKET;
+
+ nRetVal = accept(pa_nListeningSockD, &client_addr, &sin_size);
+ if(INVALID_SOCKET == nRetVal){
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: Couldn't create socket: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+int CWin32SocketInterface::sendDataOnTCP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unSize){
+ // This function sends all data in the buffer before it returns!
+ int nToSend = pa_unSize;
+ int nRetVal = 0;
+
+ while(0 < nToSend){
+ //TODO: check if open connection (socket might be closed by peer)
+ nRetVal = static_cast<int>(send(pa_nSockD, pa_pcData, nToSend, 0));
+ if(nRetVal <= 0){
+ LPSTR pacErrorMessage = getErrorMessage(WSAGetLastError());
+ DEVLOG_ERROR("TCP-Socket Send failed: %s\n", pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ break;
+ }
+ nToSend -= nRetVal;
+ pa_pcData += nRetVal;
+ }
+ return nRetVal;
+}
+
+int CWin32SocketInterface::receiveDataFromTCP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unBufSize){
+ int nRetVal;
+ do{
+ nRetVal = static_cast<int>(recv(pa_nSockD, pa_pcData, pa_unBufSize, 0));
+ } while((-1 == nRetVal) && (WSAEINTR == h_errno)); // recv got interrupt / recieving again
+ if(nRetVal == -1){
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: TCP-Socket recv() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ if(WSAECONNRESET == nLastError){
+ nRetVal = 0; //inform higher levels that the peer closed connection
+ }
+ }
+ return nRetVal;
+}
+
+CWin32SocketInterface::TSocketDescriptor CWin32SocketInterface::openUDPSendPort(char *pa_acIPAddr, unsigned short pa_nPort, TUDPDestAddr *m_ptDestAddr){
+ DEVLOG_INFO("CWin32SocketInterface: Opening UDP sending connection at: %s:%d\n", pa_acIPAddr, pa_nPort);
+ TSocketDescriptor nRetVal = INVALID_SOCKET;
+
+ nRetVal = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if(-1 != nRetVal){
+ m_ptDestAddr->sin_family = AF_INET;
+ m_ptDestAddr->sin_port = htons(pa_nPort);
+ InetPton(m_ptDestAddr->sin_family, pa_acIPAddr, &(m_ptDestAddr->sin_addr));
+ memset(&(m_ptDestAddr->sin_zero), '\0', sizeof(m_ptDestAddr->sin_zero));
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: UDP-Socket socket() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+CWin32SocketInterface::TSocketDescriptor CWin32SocketInterface::openUDPReceivePort(char *pa_acIPAddr, unsigned short pa_nPort){
+ DEVLOG_INFO("CWin32SocketInterface: Opening UDP receiving connection at: %s:%d\n", pa_acIPAddr, pa_nPort);
+ TSocketDescriptor nRetVal = INVALID_SOCKET;
+ TSocketDescriptor nSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
+
+ if(-1 != nSocket){
+ int nReuseAddrVal = 1;
+ if(0 <= setsockopt(nSocket, SOL_SOCKET, SO_REUSEADDR, (char *) &nReuseAddrVal, sizeof(nReuseAddrVal))){
+ struct sockaddr_in stSockAddr;
+ stSockAddr.sin_family = AF_INET;
+ stSockAddr.sin_port = htons(pa_nPort);
+ stSockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ memset(&(stSockAddr.sin_zero), '\0', sizeof(stSockAddr.sin_zero));
+ if(0 == bind(nSocket, (struct sockaddr *) &stSockAddr, sizeof(struct sockaddr))){
+ // setting up multicast group
+ struct ip_mreq stMReq;
+ InetPton(stSockAddr.sin_family, pa_acIPAddr, &(stMReq.imr_multiaddr));
+ stMReq.imr_interface.s_addr = htonl(INADDR_ANY);
+ setsockopt(nSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char*) &stMReq, sizeof(stMReq));
+ //if this fails we may have given a non multicasting addr. For now we accept this. May need to be changed in the future.
+
+ nRetVal = nSocket;
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: bind() failed: %d - %s\n", nLastError,pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: setsockopt(SO_REUSEADDR) failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ }
+ else{
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: Couldn't create socket: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+int CWin32SocketInterface::sendDataOnUDP(TSocketDescriptor pa_nSockD, TUDPDestAddr *pa_ptDestAddr, char* pa_pcData, unsigned int pa_unSize){
+ // This function sends all data in the buffer before it returns!
+ int nToSend = pa_unSize;
+ int nRetVal = 0;
+
+ while(0 < nToSend){
+ //TODO: check if open connection (socket might be closed by peer)
+ nRetVal = static_cast<int>(sendto(pa_nSockD, pa_pcData, nToSend, 0, (struct sockaddr *) pa_ptDestAddr, sizeof(struct sockaddr)));
+ if(nRetVal <= 0){
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: UDP-Socket Send failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ break;
+ }
+ nToSend -= nRetVal;
+ pa_pcData += nRetVal;
+ }
+ return nRetVal;
+}
+
+int CWin32SocketInterface::receiveDataFromUDP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unBufSize){
+ int nRetVal;
+ do{
+ nRetVal = static_cast<int>(recvfrom(pa_nSockD, pa_pcData, pa_unBufSize, 0, 0, 0));
+ } while((-1 == nRetVal) && (WSAEINTR == h_errno)); // recv got interrupt / recieving again
+
+ if(nRetVal == -1){ //
+ int nLastError = WSAGetLastError();
+ LPSTR pacErrorMessage = getErrorMessage(nLastError);
+ DEVLOG_ERROR("CWin32SocketInterface: UDP-Socket recvfrom() failed: %d - %s\n", nLastError, pacErrorMessage);
+ LocalFree(pacErrorMessage);
+ }
+ return nRetVal;
+}
+
+LPSTR CWin32SocketInterface::getErrorMessage(int pa_nErrorNumber){
+ LPSTR pacErrorMessage = NULL;
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL, pa_nErrorNumber, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), pacErrorMessage, 0,
+ NULL);
+ return pacErrorMessage;
+}
diff --git a/src/arch/win32/win32socketinterf.h b/src/arch/win32/win32socketinterf.h
new file mode 100644
index 000000000..cabc11cb4
--- /dev/null
+++ b/src/arch/win32/win32socketinterf.h
@@ -0,0 +1,38 @@
+/*******************************************************************************
+ * Copyright (c) 2010 - 2014 ACIN, fortiss GmbH
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Alois Zoitl, Ingo Hegny - initial API and implementation and/or initial documentation
+ *******************************************************************************/
+#ifndef BSDSOCKETINTERF_H_
+#define BSDSOCKETINTERF_H_
+
+
+class CWin32SocketInterface {
+ public:
+ typedef SOCKET TSocketDescriptor;
+ typedef struct sockaddr_in TUDPDestAddr;
+
+ static void closeSocket(TSocketDescriptor pa_nSockD);
+ static TSocketDescriptor openTCPServerConnection(char *pa_acIPAddr, unsigned short pa_nPort);
+ static TSocketDescriptor openTCPClientConnection(char *pa_acIPAddr, unsigned short pa_nPort);
+ static TSocketDescriptor acceptTCPConnection(TSocketDescriptor pa_nListeningSockD);
+ static int sendDataOnTCP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unSize);
+ static int receiveDataFromTCP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unBufSize);
+
+ static TSocketDescriptor openUDPSendPort(char *pa_acIPAddr, unsigned short pa_nPort, TUDPDestAddr *m_ptDestAddr);
+ static TSocketDescriptor openUDPReceivePort(char *pa_acIPAddr, unsigned short pa_nPort);
+ static int sendDataOnUDP(TSocketDescriptor pa_nSockD, TUDPDestAddr *pa_ptDestAddr, char* pa_pcData, unsigned int pa_unSize);
+ static int receiveDataFromUDP(TSocketDescriptor pa_nSockD, char* pa_pcData, unsigned int pa_unBufSize);
+
+ private:
+ CWin32SocketInterface(); //this function is not implemented as we don't want instances of this class
+
+ static LPSTR getErrorMessage(int pa_nErrorNumber);
+};
+
+#endif /* BSDSOCKETINTERF_H_ */
diff --git a/src/core/cominfra/ipcomlayer.cpp b/src/core/cominfra/ipcomlayer.cpp
index 69a96392a..fecde0102 100644
--- a/src/core/cominfra/ipcomlayer.cpp
+++ b/src/core/cominfra/ipcomlayer.cpp
@@ -228,7 +228,7 @@ void CIPComLayer::handledConnectedDataRecv(){
void CIPComLayer::handleConnectionAttemptInConnected(){
//accept and immediately close the connection to tell the client that we are not available
- //sofar the best option I've found for handling single connection servers
+ //so far the best option I've found for handling single connection servers
CIPComSocketHandler::TSocketDescriptor socketID = CIPComSocketHandler::acceptTCPConnection(m_nListeningID);
CIPComSocketHandler::closeSocket(socketID);
}

Back to the top