Browse Source

modified listen/accept/reader logic to run under linux

Leon Urbas 10 years ago
parent
commit
6cb41db650
2 changed files with 41 additions and 33 deletions
  1. 37 31
      examples/networklayer.c
  2. 4 2
      src/ua_transport_binary.c

+ 37 - 31
examples/networklayer.c

@@ -3,20 +3,20 @@
 
 #ifdef WIN32
 #pragma comment (lib,"ws2_32.lib")
+#include <sys/types.h>
+#include <Windows.h>
+#include <ws2tcpip.h>
 #define CLOSESOCKET(S) closesocket(S); \
 	WSACleanup();
-	#define IOCTLSOCKET ioctlsocket
-	#include <sys/types.h>
-	#include <Windows.h>
-	#include <ws2tcpip.h>
+#define IOCTLSOCKET ioctlsocket
 #else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/socketvar.h>
+#include <unistd.h> // read, write, close
 #define CLOSESOCKET(S) close(S)
-	#define IOCTLSOCKET ioctl
-	#include <sys/socket.h>
-	#include <netinet/in.h>
-	#include <sys/socketvar.h>
-	#include <unistd.h> // read, write, close
-#endif
+#define IOCTLSOCKET ioctl
+#endif /* WIN32 */
 
 #include <stdlib.h> // exit
 #include <errno.h> // errno, EINTR
@@ -122,11 +122,11 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 				//FIXME: handle errors
 				DBG_ERR(printf("UA_Stack_msgLoop - errno={%d,%s}\n", errno, strerror(errno)));
 				break;
-			case EAGAIN:
-			default:
+			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"));
 			}
 		}
@@ -136,7 +136,8 @@ UA_Int32 NL_msgLoop(NL_data* nl, struct timeval *tv, UA_Int32(*worker)(void*), v
 			DBG_VERBOSE(printf("UA_Stack_msgLoop - activities on %d handles\n",result));
 			UA_list_iteratePayload(&(nl->connections),NL_checkFdSet);
 		}
-		worker(arg);
+		// Calling worker here would execute worker any times we had received something or were interrupted
+		// worker(arg);
 	}
 
 	return UA_SUCCESS;
@@ -156,7 +157,8 @@ void* NL_TCP_reader(NL_Connection *c) {
 	UA_alloc((void**)&(readBuffer.data),localBuffers.recvBufferSize);
 
 
-	if (c->state  != CONNECTIONSTATE_CLOSE) {
+	UA_TL_Connection_getState(c->connection, &connectionState);
+	if (connectionState  != CONNECTIONSTATE_CLOSE) {
 		DBG_VERBOSE(printf("NL_TCP_reader - enter read\n"));
 
 #ifdef WIN32
@@ -181,20 +183,22 @@ void* NL_TCP_reader(NL_Connection *c) {
 			{
 				UA_NodeId serviceRequestType;
 				UA_NodeId_decodeBinary(&readBuffer, &pos,&serviceRequestType);
-				UA_NodeId_printf("Service Type\n",&serviceRequestType);
+				UA_NodeId_printf("NL_TCP_reader - Service Type\n",&serviceRequestType);
 			}
 #endif
 
 			TL_Process((c->connection),&readBuffer);
 		} else {
-//TODO close connection - what does close do?
-			c->state = CONNECTIONSTATE_CLOSE;
-			//c->connection.connectionState = CONNECTIONSTATE_CLOSE;
-			perror("ERROR reading from socket1");
+			perror("NL_TCP_reader - ERROR reading from socket1");
+			UA_TL_Connection_setState(c->connection, CONNECTIONSTATE_CLOSE);
 		}
 	}
+
 	UA_TL_Connection_getState(c->connection, &connectionState);
+	printf("NL_TCP_reader - connectionState=%d\n",connectionState);
 	if (connectionState == CONNECTIONSTATE_CLOSE) {
+		printf("NL_TCP_reader - closing connection");
+		// set connection's state to CONNECTIONSTATE_CLOSED and call callback
 		UA_TL_Connection_close(c->connection);
 #ifndef MULTITHREADING
 		DBG_VERBOSE(printf("NL_TCP_reader - search element to remove\n"));
@@ -213,9 +217,11 @@ void* NL_TCP_reader(NL_Connection *c) {
 /** the tcp reader thread */
 void* NL_TCP_readerThread(NL_Connection *c) {
 	// just loop, NL_TCP_Reader will call the stack
+	UA_Int32 connectionState;
 	do {
 		NL_TCP_reader(c);
-	} while (c->connection.connectionState != CONNECTIONSTATE_CLOSED);
+		UA_TL_Connection_getState(c->connection, &connectionState);
+	} while (connectionState != CONNECTIONSTATE_CLOSED);
 	// clean up
 	UA_free(c);
 	pthread_exit(UA_NULL);
@@ -358,16 +364,16 @@ void* NL_TCP_accept(NL_Connection* c) {
 #ifdef MULTITHREADING
 void* NL_TCP_listenThread(NL_Connection* c) {
 	NL_data* tld = c->networkLayer;
-	do {
-		DBG_VERBOSE(printf("NL_TCP_listenThread - enter listen\n"));
-		int retval = listen(c->connectionHandle, tld->tld->maxConnections);
-		DBG_VERBOSE(printf("NL_TCP_listenThread - leave listen, retval=%d\n", retval));
-
-		if (retval < 0) {
-			// TODO: Error handling
-			perror("NL_TCP_listen");
-			DBG_ERR(printf("NL_TCP_listen retval=%d, errno={%d,%s}\n", retval, errno, strerror(errno)));
-		} else {
+
+	DBG_VERBOSE(printf("NL_TCP_listenThread - enter listen\n"));
+	int retval = listen(c->connectionHandle, tld->tld->maxConnections);
+	DBG_VERBOSE(printf("NL_TCP_listenThread - leave listen, retval=%d\n", retval));
+	if (retval < 0) {
+		// TODO: Error handling
+		perror("NL_TCP_listen");
+		DBG_ERR(printf("NL_TCP_listen retval=%d, errno={%d,%s}\n", retval, errno, strerror(errno)));
+	} else {
+		do {
 			NL_TCP_accept(c);
 		}
 	} while (UA_TRUE);

+ 4 - 2
src/ua_transport_binary.c

@@ -101,8 +101,10 @@ 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);
-
-	UA_TL_Connection_close(connection);
+	// actually closing the connection should be handled 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;
 }