Prechádzať zdrojové kódy

opcuaServerMini: a flat memory model mini server with neglectable
footprint and functionality

Leon Urbas 10 rokov pred
rodič
commit
8d032b9822
2 zmenil súbory, kde vykonal 234 pridanie a 1 odobranie
  1. 6 1
      examples/src/Makefile.am
  2. 228 0
      examples/src/opcuaServerMini.c

+ 6 - 1
examples/src/Makefile.am

@@ -13,7 +13,7 @@ __top_builddir__bin_exampleServerMT_SOURCES = opcuaServerMT.c networklayer.c
 __top_builddir__bin_exampleServerMT_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
 
 else
-bin_PROGRAMS += $(top_builddir)/bin/exampleServer $(top_builddir)/bin/exampleServerACPLT
+bin_PROGRAMS += $(top_builddir)/bin/exampleServer $(top_builddir)/bin/exampleServerACPLT $(top_builddir)/bin/exampleServerMini
 
 __top_builddir__bin_exampleServer_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServer_SOURCES = opcuaServer.c networklayer.c
@@ -22,4 +22,9 @@ __top_builddir__bin_exampleServer_LDADD= $(top_builddir)/lib/libopen62541.a $(GL
 __top_builddir__bin_exampleServerACPLT_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
 __top_builddir__bin_exampleServerACPLT_SOURCES = opcuaServerACPLT.c networklayer.c
 __top_builddir__bin_exampleServerACPLT_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
+
+__top_builddir__bin_exampleServerMini_CFLAGS = -I$(top_builddir)/src -I$(top_builddir)/include $(GLOBAL_AM_CFLAGS)
+__top_builddir__bin_exampleServerMini_SOURCES = opcuaServerMini.c  networklayer.c
+__top_builddir__bin_exampleServerMini_LDADD= $(top_builddir)/lib/libopen62541.a $(GLOBAL_AM_LDADD)
+
 endif

+ 228 - 0
examples/src/opcuaServerMini.c

@@ -0,0 +1,228 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <memory.h>
+
+#include "opcua.h"
+#include "ua_transport.h"
+#include "ua_transport_binary.h"
+#include "networklayer.h"
+
+#ifdef LINUX
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <sys/socketvar.h>
+#include <unistd.h>
+
+void server_run();
+
+#endif
+
+#define PORT 16664
+#define MAXMSG 512
+#define BUFFER_SIZE 8192
+
+int main(void) {
+
+#ifdef LINUX
+	printf("Starting open62541 demo server on port %d\n", PORT);
+	server_run();
+#endif
+
+	return EXIT_SUCCESS;
+}
+
+#ifdef LINUX
+
+UA_Byte ack_msg_buf[] = { 					0x41, 0x43, /* ..m...AC */
+		0x4b, 0x46, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff, /* KF...... */
+		0xff, 0xff, 0x00, 0x20, 0x00, 0x00, 0x00, 0x20, /* ... ...  */
+		0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x01, 0x00, /* ...@.... */
+		0x00, 0x00                                      /* .. */
+};
+UA_ByteString ack_msg = { sizeof(ack_msg_buf), ack_msg_buf };
+UA_ByteString* ack_msg_gb[] = { &ack_msg };
+
+
+UA_Byte opn_msg_buf[] = {                   0x4f, 0x50, /* ......OP */
+		0x4e, 0x46, 0x88, 0x00, 0x00, 0x00, 0x19, 0x00, /* NF...... */
+		0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x68, 0x74, /* ../...ht */
+		0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x63, /* tp://opc */
+		0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69, /* foundati */
+		0x6f, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x55, /* on.org/U */
+		0x41, 0x2f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, /* A/Securi */
+		0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, /* tyPolicy */
+		0x23, 0x4e, 0x6f, 0x6e, 0x65, 0xff, 0xff, 0xff, /* #None... */
+		0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00, /* .....3.. */
+		0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc1, /* ........ */
+		0x01, 0x10, 0x56, 0x73, 0x9e, 0xdf, 0x63, 0xcf, /* ..Vs..c. */
+		0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+		0x00, 0xff, 0xff, 0xff, 0xff, 0x19, 0x00, 0x00, /* ........ */
+		0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+		0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+		0x00, 0x01, 0x00, 0x00, 0x00, 0x48              /* .....H */ };
+UA_ByteString opn_msg = { sizeof(opn_msg_buf), opn_msg_buf };
+UA_ByteString* opn_msg_gb[] = { &opn_msg };
+
+UA_Byte gep_msg_buf[] = {           0x4d, 0x53, /* ......MS */
+0x47, 0x46, 0x8b, 0x01, 0x00, 0x00, 0x19, 0x00, /* GF...... */
+0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00, /* ......4. */
+0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x01, 0x00, /* ........ */
+0xaf, 0x01, 0x2c, 0xc1, 0x73, 0x9e, 0xdf, 0x63, /* ..,.s..c */
+0xcf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* ........ */
+0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00, /* ........ */
+0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, 0x74, 0x63, /* ..opc.tc */
+0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, 0x2e, 0x30, /* p://10.0 */
+0x2e, 0x35, 0x33, 0x2e, 0x31, 0x39, 0x38, 0x3a, /* .53.198: */
+0x31, 0x36, 0x36, 0x36, 0x34, 0x27, 0x00, 0x00, /* 16664'.. */
+0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* .http:// */
+0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, /* open6254 */
+0x31, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x61, /* 1.info/a */
+0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, /* pplicati */
+0x6f, 0x6e, 0x73, 0x2f, 0x34, 0x37, 0x31, 0x31, /* ons/4711 */
+0x25, 0x00, 0x00, 0x00, 0x68, 0x74, 0x74, 0x70, /* %...http */
+0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x36, /* ://open6 */
+0x32, 0x35, 0x34, 0x31, 0x2e, 0x69, 0x6e, 0x66, /* 2541.inf */
+0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63, /* o/produc */
+0x74, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73, /* t/releas */
+0x65, 0x03, 0x02, 0x00, 0x00, 0x00, 0x45, 0x4e, /* e.....EN */
+0x19, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20, /* ....The  */
+0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34, /* open6254 */
+0x31, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, /* 1 applic */
+0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00, /* ation... */
+0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */
+0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, /* ........ */
+0xff, 0x01, 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, /* ...../.. */
+0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, /* .http:// */
+0x6f, 0x70, 0x63, 0x66, 0x6f, 0x75, 0x6e, 0x64, /* opcfound */
+0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x72, /* ation.or */
+0x67, 0x2f, 0x55, 0x41, 0x2f, 0x53, 0x65, 0x63, /* g/UA/Sec */
+0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c, /* urityPol */
+0x69, 0x63, 0x79, 0x23, 0x4e, 0x6f, 0x6e, 0x65, /* icy#None */
+0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, /* ........ */
+0x6d, 0x79, 0x2d, 0x61, 0x6e, 0x6f, 0x6e, 0x79, /* my-anony */
+0x6d, 0x6f, 0x75, 0x73, 0x2d, 0x70, 0x6f, 0x6c, /* mous-pol */
+0x69, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0xff, /* icy..... */
+0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* ........ */
+0xff, 0xff, 0xff, 0x41, 0x00, 0x00, 0x00, 0x68, /* ...A...h */
+0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70, /* ttp://op */
+0x63, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, /* cfoundat */
+0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, /* ion.org/ */
+0x55, 0x41, 0x2d, 0x50, 0x72, 0x6f, 0x66, 0x69, /* UA-Profi */
+0x6c, 0x65, 0x2f, 0x54, 0x72, 0x61, 0x6e, 0x73, /* le/Trans */
+0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x61, 0x74, /* port/uat */
+0x63, 0x70, 0x2d, 0x75, 0x61, 0x73, 0x63, 0x2d, /* cp-uasc- */
+0x75, 0x61, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, /* uabinary */
+0x00                                            /* . */
+};
+UA_ByteString gep_msg = { sizeof(gep_msg_buf), gep_msg_buf };
+UA_ByteString* gep_msg_gb[] = { &gep_msg };
+
+UA_Int32 myProcess(TL_Connection* connection, const UA_ByteString* msg) {
+	switch (*((UA_Int32*) &(msg->data[0]))) { // compare first four bytes
+		case 0x464c4548: // HELF
+			connection->writerCallback(connection, (const UA_ByteString**) &ack_msg_gb, 1);
+		break;
+		case 0x464e504f: // OPNF
+			connection->writerCallback(connection, (const UA_ByteString**) &opn_msg_gb, 1);
+		break;
+		case 0x464f4c43: // CLOF
+			connection->connectionState = CONNECTIONSTATE_CLOSE;
+		break;
+		case 0x4647534d: // MSGF
+			switch (*((UA_Int16*) &(msg->data[26]))) {
+				case (UA_Int16) 0xAC01: // 428 - GetEndpointsRequest
+					printf("server_run - GetEndpointsRequest\n");
+					connection->writerCallback(connection, (const UA_ByteString**) &gep_msg_gb, 1);
+				break;
+				default:
+					//FIXME: send a real error message
+					connection->writerCallback(connection, (const UA_ByteString**) &gep_msg_gb, 1);
+				break;
+			}
+		break;
+	}
+	return UA_SUCCESS;
+}
+void server_run() {
+	TL_Connection connection;
+	connection.connectionState = CONNECTIONSTATE_CLOSED;
+	connection.writerCallback = (TL_Writer) NL_TCP_writer;
+	connection.localConf.maxChunkCount = 1;
+	connection.localConf.maxMessageSize = BUFFER_SIZE;
+	connection.localConf.protocolVersion = 0;
+	connection.localConf.recvBufferSize = BUFFER_SIZE;
+	connection.localConf.recvBufferSize = BUFFER_SIZE;
+
+	UA_ByteString slMessage = { -1, UA_NULL };
+
+	int optval = 1;
+	int sockfd, newsockfd, portno, clilen;
+	char buffer[BUFFER_SIZE];
+	struct sockaddr_in serv_addr, cli_addr;
+	int n;
+
+	/* First call to socket() function */
+	sockfd = socket(PF_INET, SOCK_STREAM, 0);
+	if (sockfd < 0) {
+		perror("ERROR opening socket");
+		exit(1);
+	}
+
+	/* Initialize socket structure */
+    memset((void *) &serv_addr, 0, sizeof(serv_addr));
+	portno = PORT;
+	serv_addr.sin_family = AF_INET;
+	serv_addr.sin_addr.s_addr = INADDR_ANY;
+	serv_addr.sin_port = htons(portno);
+
+	if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval) == -1) {
+		perror("setsockopt");
+		exit(1);
+	}
+
+	/* Now bind the host address using bind() call.*/
+	if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
+		perror("ERROR on binding");
+		exit(1);
+	}
+
+	/* Now start listening for the clients, here process will
+	 * go in sleep mode and will wait for the incoming connection
+	 */
+	while (listen(sockfd, 5) != -1) {
+		clilen = sizeof(cli_addr);
+		/* Accept actual connection from the client */
+		newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, (socklen_t*) &clilen);
+		if (newsockfd < 0) {
+			perror("ERROR on accept");
+			exit(1);
+		}
+
+		printf("server_run - connection accepted: %i, state: %i\n", newsockfd, connection.connectionState);
+		connection.connectionHandle = newsockfd;
+		do {
+            memset(buffer, 0, BUFFER_SIZE);
+			n = read(newsockfd, buffer, BUFFER_SIZE);
+			if (n > 0) {
+                slMessage.data = (UA_Byte*) buffer;
+				slMessage.length = n;
+				UA_ByteString_printx("server_run - received=",&slMessage);
+				myProcess(&connection, &slMessage);
+			} else if (n <= 0) {
+				perror("ERROR reading from socket1");
+				connection.connectionState = CONNECTIONSTATE_CLOSE;
+			}
+		} while(connection.connectionState != CONNECTIONSTATE_CLOSE);
+		shutdown(newsockfd,2);
+		close(newsockfd);
+		connection.connectionState = CONNECTIONSTATE_CLOSED;
+	}
+	shutdown(sockfd,2);
+	close(sockfd);
+}
+
+#endif