123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340 |
- #include <stdio.h>
- #include <stdlib.h>
- #include <memory.h>
- #include <errno.h>
- #include "ua_statuscodes.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,
- 0x4b, 0x46, 0x1c, 0x00, 0x00, 0x00, 0xff, 0xff,
- 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,
- 0x4e, 0x46, 0x88, 0x00, 0x00, 0x00, 0x19, 0x00,
- 0x00, 0x00, 0x2f, 0x00, 0x00, 0x00, 0x68, 0x74,
- 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x63,
- 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x55,
- 0x41, 0x2f, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
- 0x74, 0x79, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79,
- 0x23, 0x4e, 0x6f, 0x6e, 0x65, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0x33, 0x00, 0x00,
- 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xc1,
- 0x01, 0x10, 0x56, 0x73, 0x9e, 0xdf, 0x63, 0xcf,
- 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
- };
- UA_ByteString opn_msg = { sizeof(opn_msg_buf), opn_msg_buf };
- UA_ByteString* opn_msg_gb[] = { &opn_msg };
- UA_Byte scm_msg_buf[] = { 0x4d, 0x53,
- 0x47, 0x46, 0x8b, 0x01, 0x00, 0x00, 0x19, 0x00,
- 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x34, 0x00,
- 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
- };
- UA_Byte rsp_msg_buf[] = { 0x01, 0x00,
- 0xaf, 0x01, 0x2c, 0xc1, 0x73, 0x9e, 0xdf, 0x63,
- 0xcf, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00
- };
- UA_Byte gep_msg_buf[] = {
- 0x01, 0x00, 0x00, 0x00, 0x1b, 0x00,
- 0x00, 0x00, 0x6f, 0x70, 0x63, 0x2e, 0x74, 0x63,
- 0x70, 0x3a, 0x2f, 0x2f, 0x31, 0x30, 0x2e, 0x30,
- 0x2e, 0x35, 0x33, 0x2e, 0x31, 0x39, 0x38, 0x3a,
- 0x31, 0x36, 0x36, 0x36, 0x34, 0x27, 0x00, 0x00,
- 0x00, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f,
- 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34,
- 0x31, 0x2e, 0x69, 0x6e, 0x66, 0x6f, 0x2f, 0x61,
- 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69,
- 0x6f, 0x6e, 0x73, 0x2f, 0x34, 0x37, 0x31, 0x31,
- 0x25, 0x00, 0x00, 0x00, 0x68, 0x74, 0x74, 0x70,
- 0x3a, 0x2f, 0x2f, 0x6f, 0x70, 0x65, 0x6e, 0x36,
- 0x32, 0x35, 0x34, 0x31, 0x2e, 0x69, 0x6e, 0x66,
- 0x6f, 0x2f, 0x70, 0x72, 0x6f, 0x64, 0x75, 0x63,
- 0x74, 0x2f, 0x72, 0x65, 0x6c, 0x65, 0x61, 0x73,
- 0x65, 0x03, 0x02, 0x00, 0x00, 0x00, 0x45, 0x4e,
- 0x19, 0x00, 0x00, 0x00, 0x54, 0x68, 0x65, 0x20,
- 0x6f, 0x70, 0x65, 0x6e, 0x36, 0x32, 0x35, 0x34,
- 0x31, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x00, 0x00, 0x00,
- 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,
- 0x6f, 0x70, 0x63, 0x66, 0x6f, 0x75, 0x6e, 0x64,
- 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x72,
- 0x67, 0x2f, 0x55, 0x41, 0x2f, 0x53, 0x65, 0x63,
- 0x75, 0x72, 0x69, 0x74, 0x79, 0x50, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x23, 0x4e, 0x6f, 0x6e, 0x65,
- 0x01, 0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00,
- 0x6d, 0x79, 0x2d, 0x61, 0x6e, 0x6f, 0x6e, 0x79,
- 0x6d, 0x6f, 0x75, 0x73, 0x2d, 0x70, 0x6f, 0x6c,
- 0x69, 0x63, 0x79, 0x00, 0x00, 0x00, 0x00, 0xff,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0x41, 0x00, 0x00, 0x00, 0x68,
- 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x70,
- 0x63, 0x66, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x74,
- 0x69, 0x6f, 0x6e, 0x2e, 0x6f, 0x72, 0x67, 0x2f,
- 0x55, 0x41, 0x2d, 0x50, 0x72, 0x6f, 0x66, 0x69,
- 0x6c, 0x65, 0x2f, 0x54, 0x72, 0x61, 0x6e, 0x73,
- 0x70, 0x6f, 0x72, 0x74, 0x2f, 0x75, 0x61, 0x74,
- 0x63, 0x70, 0x2d, 0x75, 0x61, 0x73, 0x63, 0x2d,
- 0x75, 0x61, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79,
- 0x00
- };
- UA_Byte csr_msg_buf[] = {
- 0x01, 0x01, 0x9a, 0x02, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
- 0x00, 0x00, 0x00, 0x00
- };
- UA_Byte asr_msg_buf[] = {
- 0xff, 0xff, 0xff, 0xff, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
- };
- UA_ByteString scm_msg = { sizeof(scm_msg_buf), scm_msg_buf };
- UA_ByteString rsp_msg = { sizeof(rsp_msg_buf), rsp_msg_buf };
- UA_ByteString* sf_msg_gb[] = { &scm_msg, &rsp_msg };
- UA_ByteString gep_msg = { sizeof(gep_msg_buf), gep_msg_buf };
- UA_ByteString* gep_msg_gb[] = { &scm_msg, &rsp_msg, &gep_msg };
- UA_ByteString csr_msg = { sizeof(csr_msg_buf), csr_msg_buf };
- UA_ByteString* csr_msg_gb[] = { &scm_msg, &rsp_msg, &csr_msg };
- UA_ByteString asr_msg = { sizeof(asr_msg_buf), asr_msg_buf };
- UA_ByteString* asr_msg_gb[] = { &scm_msg, &rsp_msg, &asr_msg };
- UA_Int32 myProcess(TL_Connection* connection, const UA_ByteString* msg) {
- switch (*((UA_Int32*) &(msg->data[0]))) {
- case 0x464c4548:
- connection->writerCallback(connection, (const UA_ByteString**) &ack_msg_gb, 1);
- break;
- case 0x464e504f:
- connection->writerCallback(connection, (const UA_ByteString**) &opn_msg_gb, 1);
- break;
- case 0x464f4c43:
- connection->connectionState = CONNECTIONSTATE_CLOSE;
- break;
- case 0x4647534d:
- switch (*((UA_Int16*) &(msg->data[26]))) {
- case 428:
- #pragma GCC diagnostic push
- #pragma GCC diagnostic ignored "-Wstrict-aliasing"
- printf("server_run - GetEndpointsRequest\n");
- *(UA_Int32*) (&scm_msg_buf[4]) = sizeof(scm_msg_buf) + sizeof(rsp_msg_buf) + sizeof(gep_msg_buf);
- *(UA_Int16*) (&rsp_msg_buf[2]) = *(UA_Int16*) (&msg->data[26]) + 3;
- *(UA_Int32*) (&rsp_msg_buf[16]) = UA_STATUSCODE_GOOD;
- connection->writerCallback(connection, (const UA_ByteString**) &gep_msg_gb, 3);
- break;
- case 461:
- printf("server_run - CreateSessionRequest\n");
- *(UA_Int32*) (&scm_msg_buf[4]) = sizeof(scm_msg_buf) + sizeof(rsp_msg_buf) + sizeof(csr_msg_buf);
- *(UA_Int16*) (&rsp_msg_buf[2]) = *(UA_Int16*) (&msg->data[26]) + 3;
- *(UA_Int32*) (&rsp_msg_buf[16]) = UA_STATUSCODE_GOOD;
- connection->writerCallback(connection, (const UA_ByteString**) &csr_msg_gb, 3);
- break;
- case 467:
- printf("server_run - ActivateSessionRequest\n");
- *(UA_Int32*) (&scm_msg_buf[4]) = sizeof(scm_msg_buf) + sizeof(rsp_msg_buf) + sizeof(asr_msg_buf);
- *(UA_Int16*) (&rsp_msg_buf[2]) = *(UA_Int16*) (&msg->data[26]) + 3;
- *(UA_Int32*) (&rsp_msg_buf[16]) = UA_STATUSCODE_GOOD;
- connection->writerCallback(connection, (const UA_ByteString**) &asr_msg_gb, 3);
- break;
- default:
- *(UA_Int32*) (&scm_msg_buf[4]) = sizeof(scm_msg_buf) + sizeof(rsp_msg_buf);
- *(UA_Int16*) (&rsp_msg_buf[2]) = UA_SERVICEFAULT_NS0 + 2;
- *(UA_Int32*) (&rsp_msg_buf[16]) = UA_STATUSCODE_BADNOTIMPLEMENTED;
- #pragma GCC diagnostic pop
- printf("server_run - unknown request %d\n", *((UA_Int16*) &(msg->data[26])));
- connection->writerCallback(connection, (const UA_ByteString**) &sf_msg_gb, 2);
- break;
- }
- break;
- }
- return UA_SUCCESS;
- }
- UA_Int32 myWriter(struct TL_Connection const * c, UA_ByteString const * const * gather_buf, UA_UInt32 gather_len) {
- struct iovec iov[gather_len];
- UA_UInt32 total_len = 0;
- for(UA_UInt32 i=0;i<gather_len;i++) {
- iov[i].iov_base = gather_buf[i]->data;
- iov[i].iov_len = gather_buf[i]->length;
- total_len += gather_buf[i]->length;
- }
- struct msghdr message;
- message.msg_name = UA_NULL;
- message.msg_namelen = 0;
- message.msg_iov = iov;
- message.msg_iovlen = gather_len;
- message.msg_control = UA_NULL;
- message.msg_controllen = 0;
- message.msg_flags = 0;
- UA_UInt32 nWritten = 0;
- while (nWritten < total_len) {
- int n=0;
- do {
- DBG_VERBOSE(printf("myWriter - enter write with %d bytes to write\n",total_len));
- n = sendmsg(c->connectionHandle, &message, 0);
- DBG_VERBOSE(printf("myWriter - leave write with n=%d,errno={%d,%s}\n",n,(n>0)?0:errno,(n>0)?"":strerror(errno)));
- } while (n == -1L && errno == EINTR);
- if (n >= 0) {
- nWritten += n;
- break;
-
- } else {
- break;
-
- }
- }
- return UA_SUCCESS;
- }
- void server_run() {
- TL_Connection connection;
- connection.connectionState = CONNECTIONSTATE_CLOSED;
- connection.writerCallback = (TL_Writer) myWriter;
- 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;
-
- sockfd = socket(PF_INET, SOCK_STREAM, 0);
- if (sockfd < 0) {
- perror("ERROR opening socket");
- exit(1);
- }
-
- 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);
- }
-
- if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
- perror("ERROR on binding");
- exit(1);
- }
-
- while (listen(sockfd, 5) != -1) {
- clilen = sizeof(cli_addr);
-
- 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;
- DBG(printf("server_run - received=%d\n",n));
- 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
|