/* * %CopyrightBegin% * * Copyright Ericsson AB 2002-2016. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * %CopyrightEnd% * */ /* C-server for test of IC. * * The C-node implemented here connects to its peer node, waits for * one message, evaluates the message, returns an result message, and * terminates. * * TODO: * * 1. XXX #includes for VxWorks, Windows */ #include #include #ifndef __WIN32__ # include #endif #include #ifdef __WIN32__ # include # include #elif defined VXWORKS # include # include #else # include #endif #include #ifdef __WIN32__ # include # include #else # include # include # include # include # include #endif #include "ic.h" #include "ei.h" #include "erl_interface.h" #include "eicode.h" #include "m_i__s.h" #include "m__s.h" #ifdef __WIN32__ typedef struct { long tv_sec; long tv_usec; } MyTimeval; #else typedef struct timeval MyTimeval; #endif static void my_gettimeofday(MyTimeval *tv); static void showtime(MyTimeval *start, MyTimeval *stop); static void usage(void); static void done(int r); #define HOSTNAMESZ 255 #define NODENAMESZ 512 #define INBUFSZ 10 #define OUTBUFSZ 0 #define MAXTRIES 5 static char *progname; /* main */ #ifdef VXWORKS int c_server(int argc, char **argv) #else int main(int argc, char **argv) #endif { struct hostent *hp; MyTimeval start, stop; int i, fd, ires, tries; CORBA_Environment *env; char *this_node_name = NULL; char *peer_node = NULL; char *cookie = NULL; char host[HOSTNAMESZ + 1]; char this_node[NODENAMESZ + 1]; erlang_msg msg; int status, loop; #ifdef __WIN32__ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2, 0); if (WSAStartup(wVersionRequested, &wsaData) != 0) { fprintf(stderr, "Could not load winsock2 v2.0 compatible DLL"); exit(1); } #endif progname = argv[0]; host[HOSTNAMESZ] = '\0'; if (gethostname(host, HOSTNAMESZ + 1) < 0) { fprintf(stderr, "Can't find own hostname\n"); done(1); } if ((hp = gethostbyname(host)) == 0) { fprintf(stderr, "Can't get ip address for host %s\n", host); done(1); } for (i = 1; i < argc; i++) { if (strcmp(argv[i], "-help") == 0) { usage(); done(0); } else if (strcmp(argv[i], "-this-node-name") == 0) { i++; this_node_name = argv[i]; } else if (strcmp(argv[i], "-peer-node") == 0) { i++; peer_node = argv[i]; } else if (strcmp(argv[i], "-cookie") == 0) { i++; cookie = argv[i]; } else { fprintf(stderr, "Error : invalid argument \"%s\"\n", argv[i]); usage(); done(1); } } if (this_node_name == NULL || peer_node == NULL || cookie == NULL) { fprintf(stderr, "Error: missing option\n"); usage(); done(1); } /* Behead hostname at first dot */ for (i=0; host[i] != '\0'; i++) { if (host[i] == '.') { host[i] = '\0'; break; } } sprintf(this_node, "%s@%s", this_node_name, host); fprintf(stderr, "c_server: this node: \"%s\"\n", this_node); fprintf(stderr, "c_server: peer node: \"%s\"\n", peer_node); /* initialize erl_interface */ erl_init(NULL, 0); for (tries = 0; tries < MAXTRIES; tries++) { /* connect to peer node */ ires = erl_connect_xinit(host, this_node_name, this_node, (struct in_addr *)*hp->h_addr_list, cookie, 0); fprintf(stderr, "c_server: erl_connect_xinit(): %d\n", ires); fd = erl_connect(peer_node); fprintf(stderr, "c_server: erl_connect(): %d\n", fd); if (fd >= 0) break; fprintf(stderr, "c_server: cannot connect, retrying\n"); } if (fd < 0) { fprintf(stderr, "c_server: cannot connect, exiting\n"); done(1); } env = CORBA_Environment_alloc(INBUFSZ, OUTBUFSZ); env->_fd = fd; status = 1; loop = 1; my_gettimeofday(&start); while (status >= 0 && loop > 0) { status = ei_receive_encoded(env->_fd, &env->_inbuf, &env->_inbufsz, &msg, &env->_iin); switch(status) { case ERL_SEND: case ERL_REG_SEND: /* get result */ m_i__switch(NULL, env); switch(env->_major) { case CORBA_NO_EXCEPTION: break; case CORBA_SYSTEM_EXCEPTION: fprintf(stderr, "Request failure, reason : %s\n", (char *) CORBA_exception_value(env)); CORBA_exception_free(env); break; default: /* Should not happen */ CORBA_exception_free(env); break; } /* send back result data */ if (env->_iout > 0) ei_send_encoded(env->_fd, &env->_caller, env->_outbuf, env->_iout); loop = 0; break; case ERL_TICK: break; default: if (status < 0) { fprintf(stderr, "Status negative: %d\n", status); loop = 0; } break; } } my_gettimeofday(&stop); showtime(&start, &stop); erl_close_connection(fd); CORBA_free(env->_inbuf); CORBA_free(env->_outbuf); CORBA_free(env); if (status < 0) done(-status); else done(0); } static void usage() { fprintf(stderr, "Usage: %s [-help] -this-node-name " "-peer-node -cookie \n", progname); fprintf(stderr, "Example:\n %s -this-node-name kalle " "-peer-node olle@home -cookie oa678er\n", progname); } static void done(int r) { #ifdef __WIN32__ WSACleanup(); #endif exit(r); } static void showtime(MyTimeval *start, MyTimeval *stop) { MyTimeval elapsed; elapsed.tv_sec = stop->tv_sec - start->tv_sec; elapsed.tv_usec = stop->tv_usec - start->tv_usec; while (elapsed.tv_usec < 0) { elapsed.tv_sec -= 1; elapsed.tv_usec += 1000000; } fprintf(stderr,"%ld.%06ld seconds\n",elapsed.tv_sec, elapsed.tv_usec); } static void my_gettimeofday(MyTimeval *tv) #ifdef __WIN32__ #define EPOCH_JULIAN_DIFF 11644473600i64 { SYSTEMTIME t; FILETIME ft; LONGLONG lft; GetSystemTime(&t); SystemTimeToFileTime(&t, &ft); memcpy(&lft, &ft, sizeof(lft)); tv->tv_usec = (long) ((lft / 10i64) % 1000000i64); tv->tv_sec = (long) ((lft / 10000000i64) - EPOCH_JULIAN_DIFF); } #elif defined VXWORKS { int rate = sysClkRateGet(); /* Ticks per second */ unsigned long ctick = tickGet(); tv->tv_sec = ctick / rate; /* secs since reboot */ tv->tv_usec = ((ctick - (tv->tv_sec * rate))*1000000)/rate; } #else { gettimeofday(tv, NULL); } #endif