Przeglądaj źródła

resolved conflicts

Leon Urbas 10 lat temu
rodzic
commit
b38435378d
2 zmienionych plików z 58 dodań i 30 usunięć
  1. 57 28
      examples/networklayer.c
  2. 1 2
      src/ua_transport_binary.c

+ 57 - 28
examples/networklayer.c

@@ -6,8 +6,7 @@
 #include <sys/types.h>
 #include <Windows.h>
 #include <ws2tcpip.h>
-#define CLOSESOCKET(S) closesocket(S); \
-	WSACleanup();
+#define CLOSESOCKET(S) closesocket(S)
 #define IOCTLSOCKET ioctlsocket
 #else
 #include <sys/socket.h>
@@ -75,7 +74,7 @@ void NL_Connection_printf(void* payload) {
 void NL_addHandleToSet(UA_Int32 handle, NL_data* nl) {
 	FD_SET(handle, &(nl->readerHandles));
 #ifdef WIN32
-	int err = WSAGetLastError();
+	// int err = WSAGetLastError();
 #endif
 	nl->maxReaderHandle = (handle > nl->maxReaderHandle) ? handle : nl->maxReaderHandle;
 }
@@ -89,8 +88,21 @@ void NL_checkFdSet(void* payload) {
 	  c->reader((void*)c);
   }
 }
+
+#if 0 
+char _str_error[256];
+char* strerror(int errno) {
+	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+		NULL, errno,
+		MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+		&_str_error[0], 256, NULL);
+	return &_str_error[0];
+}
+#endif
+
 UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), void *arg, UA_Boolean *running)  {
 	UA_Int32 result;
+	UA_Int32 err;
 	while (*running) {
 		// determine the largest handle
 		nl->maxReaderHandle = 0;
@@ -98,51 +110,66 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 		DBG_VERBOSE(printf("\n------------\nUA_Stack_msgLoop - maxHandle=%d\n", nl->maxReaderHandle));
 
 		// copy tv, some unixes do overwrite and return the remaining time
+		// FIXME: actually we might want to do this ourselves to call the
+		// worker on a more regular cyclic basis
 		struct timeval tmptv;
 		memcpy(&tmptv,tv,sizeof(struct timeval));
 
 		// and wait
 		DBG_VERBOSE(printf("UA_Stack_msgLoop - enter select sec=%d,usec=%d\n",(UA_Int32) tmptv.tv_sec, (UA_Int32) tmptv.tv_usec));
 		result = select(nl->maxReaderHandle + 1, &(nl->readerHandles), UA_NULL, UA_NULL, &tmptv);
-
 		DBG_VERBOSE(printf("UA_Stack_msgLoop - leave select result=%d,sec=%d,usec=%d\n",result, (UA_Int32) tmptv.tv_sec, (UA_Int32) tmptv.tv_usec));
+
+		// handle timeout (winsock: result=0, unix: result=0,errno=0||EAGAIN) 
+		// and errors (winsock: result=SOCKET_ERROR (-1), unix: result = 0)
+		if (result <= 0) {
 #ifdef WIN32
-		if (result == -1) {
-			DBG_ERR(printf("UA_Stack_msgLoop - errno = { %d, %s }\n", WSAGetLastError()));
-		}
-		else if (result >= 0){ // activity on listener or client ports
+			err = (result == SOCKET_ERROR) ? WSAGetLastError() : 0;
 #else
-		if (result == 0) {
-			UA_Int32 err = errno;
-
+			err = errno;
+#endif
 			switch (err) {
+				// handle known errors
+#ifdef WIN32
+			case WSANOTINITIALISED:
+			case WSAEFAULT:
+			case WSAENETDOWN:
+			case WSAEINVAL:
+			case WSAEINTR:
+			case WSAEINPROGRESS:
+			case WSAENOTSOCK:
+#else
 			case EBADF:
 			case EINTR:
 			case EINVAL:
-				//FIXME: handle errors
-				DBG_ERR(printf("UA_Stack_msgLoop - errno={%d,%s}\n", errno, strerror(errno)));
+#endif
+				// FIXME: handle errors
+				printf("UA_Stack_msgLoop - result=%d, errno={%d,%s}\n", result, errno, strerror(errno));
 				break;
-			case EAGAIN: // timer due, call worker
-			default: //
-				DBG_VERBOSE(printf("UA_Stack_msgLoop - errno={%d,%s}\n", errno, strerror(errno)));
-				DBG_VERBOSE(printf("UA_Stack_msgLoop - call worker\n"));
-				worker(arg);
-				DBG_VERBOSE(printf("UA_Stack_msgLoop - return from worker\n"));
-			}
-		}
-
-		else if (result > 0){ // activity on listener or client ports
+			// otherwise we've got a timeout and call the worker
+#ifndef WIN32
+	        case EAGAIN:
 #endif
+			default:
+					DBG_VERBOSE(printf("UA_Stack_msgLoop - result=%d, errno={%d,%s}\n", result, errno, strerror(errno)));
+					worker(arg);
+			}
+		} else { // activity on listener or client ports
 			DBG_VERBOSE(printf("UA_Stack_msgLoop - activities on %d handles\n",result));
 			UA_list_iteratePayload(&(nl->connections),NL_checkFdSet);
+			// FIXME: Thought it would be a conceptional flaw to call the worker
+			// here. However, there is no guarantee that the timeout would be
+			// triggered, so we call it in this branch as well.
+			worker(arg);
 		}
-		// Calling worker here would execute worker any times we had received something or were interrupted
-		// worker(arg);
 	}
-
+#ifdef WIN32
+	// finally we should clean up the winsock.dll
+	WSACleanup();
+#endif
 	return UA_SUCCESS;
 }
-#endif
+#endif /* MULTITASKING */
 
 
 /** the tcp reader function */
@@ -188,13 +215,15 @@ void* NL_TCP_reader(NL_Connection *c) {
 			}
 #endif
 			TL_Process((c->connection),&readBuffer);
+		} else {
+			perror("NL_TCP_reader - ERROR reading from socket");
+			UA_TL_Connection_setState(c->connection, CONNECTIONSTATE_CLOSE);
 		}
 	}
 
 	UA_TL_Connection_getState(c->connection, &connectionState);
 	DBG_VERBOSE(printf("NL_TCP_reader - connectionState=%d\n",connectionState));
 	if (connectionState == CONNECTIONSTATE_CLOSE) {
-		DBG_VERBOSE(printf("NL_TCP_reader - closing connection"));
 		// set connection's state to CONNECTIONSTATE_CLOSED and call callback to actually close
 		UA_TL_Connection_close(c->connection);
 #ifndef MULTITHREADING

+ 1 - 2
src/ua_transport_binary.c

@@ -101,9 +101,8 @@ static UA_Int32 TL_handleMsg(UA_TL_Connection *connection, const UA_ByteString*
 static UA_Int32 TL_handleClo(UA_TL_Connection *connection, const UA_ByteString* msg, UA_UInt32* pos) {
 	UA_Int32 retval = UA_SUCCESS;
 	SL_Process(msg,pos);
-	// actually closing the connection should be handled elsewhere
+	// just prepare closing, closing and freeing structures is done elsewhere
 	// UA_TL_Connection_close(connection);
-	// here we only need to tell that we want to close
 	UA_TL_Connection_setState(connection, CONNECTIONSTATE_CLOSE);
 	return retval;
 }