00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "eripc.h"
00025 #include "eripcprivate.h"
00026 #include "eripcports.h"
00027 #include "eripcclient.h"
00028 #include "eripclog.h"
00029
00030 #include <stdio.h>
00031 #include <string.h>
00032
00033 #include <sys/types.h>
00034 #include <sys/socket.h>
00035 #include <arpa/inet.h>
00036 #include <netinet/in.h>
00037
00038
00039 int erIpcGetVersion()
00040 {
00041 return ER_IPC_VERSION;
00042 }
00043
00044
00045
00046
00047
00048 int erIpcInitServer(int channelIdx, int *sockfd, int local)
00049 {
00050 int error;
00051 int port;
00052 struct sockaddr_in serverAdr;
00053 int on = 1;
00054
00055
00056 ERIPC_WARNPRINTF("Version: %d\n", erIpcGetVersion());
00057
00058
00059 *sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00060 error = setsockopt(*sockfd, SOL_SOCKET, SO_REUSEADDR, (const char *) &on, sizeof(on));
00061 if (error)
00062 {
00063 perror("Unable to set socket options to SO_REUSEADDR");
00064 }
00065
00066 port = erIpcGetServerPort(channelIdx);
00067 if (port == ER_IPC_PORT_ILLEGAL)
00068 {
00069 ERIPC_ERRORPRINTF("Could not allocate channel %d", channelIdx);
00070 return -1;
00071 }
00072
00073 bzero(&serverAdr, sizeof(serverAdr));
00074 serverAdr.sin_family = AF_INET;
00075
00076
00077
00078
00079
00080 if (local == 1)
00081 {
00082 serverAdr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
00083 }
00084 else
00085 {
00086 serverAdr.sin_addr.s_addr = htonl(INADDR_ANY);
00087 }
00088 serverAdr.sin_port = htons(port);
00089
00090 error = bind(*sockfd, (struct sockaddr *) &serverAdr, sizeof(serverAdr));
00091 if (error)
00092 {
00093 perror("Error invoking bind");
00094 return -1;
00095 }
00096 else
00097 {
00098 char szServerIP[INET_ADDRSTRLEN + 1];
00099
00100 inet_ntop(AF_INET, &serverAdr.sin_addr, szServerIP, sizeof(szServerIP));
00101 ERIPC_WARNPRINTF("Bound successfully to %s:%d.", szServerIP, port);
00102 }
00103 return 0;
00104 }
00105
00106
00107
00108 int erIpcStartServer(int channelIdx, erMessageCB callback, char *szBuffer, int *nBuf, void *data)
00109 {
00110 int sockfd;
00111 struct sockaddr_in clientAdr;
00112 socklen_t len;
00113 int n;
00114 int nErr;
00115 int fLocal = 1;
00116 erMessageCB messageCallback = NULL;
00117 int nBufsize;
00118
00119 nErr = erIpcInitServer(channelIdx, &sockfd, fLocal);
00120 if (nErr != 0)
00121 {
00122 ERIPC_ERRORPRINTF("Failed to start IPC server");
00123 return -1;
00124 }
00125
00126 nBufsize = *nBuf;
00127 messageCallback = callback;
00128 while (1)
00129 {
00130 char szClientIP[INET_ADDRSTRLEN + 1];
00131
00132
00133 len = sizeof(clientAdr);
00134 n = recvfrom(sockfd, szBuffer, nBufsize, 0, (struct sockaddr *) &clientAdr, &len);
00135 szBuffer[n] = '\0';
00136
00137
00138 if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00139 {
00140 ERIPC_LOGPRINTF("Message %s received from %s", szBuffer, szClientIP);
00141 }
00142 *nBuf = n;
00143 messageCallback(szBuffer, nBuf, data);
00144 }
00145 }
00146
00147 int erIpcOpenServerChannel(int channelIdx, erServerChannel_t * channel)
00148 {
00149 erInternalServerChannel_t *serverChannel;
00150 int sockfd;
00151 int nErr;
00152 int fLocal = 1;
00153
00154 nErr = erIpcInitServer(channelIdx, &sockfd, fLocal);
00155 if (nErr != 0)
00156 {
00157 ERIPC_ERRORPRINTF("Failed to initialize IPC server");
00158 return -1;
00159 }
00160
00161 serverChannel = (erInternalServerChannel_t *) malloc(sizeof(erInternalServerChannel_t));
00162
00163 if (serverChannel != NULL)
00164 {
00165 *channel = (erServerChannel_t) serverChannel;
00166 }
00167 else
00168 {
00169 ERIPC_ERRORPRINTF("Out of memory.");
00170 return -1;
00171 }
00172 serverChannel->sockfd = sockfd;
00173 return 0;
00174 }
00175
00176 int erIpcGetServerFd(erServerChannel_t channel)
00177 {
00178 erInternalServerChannel_t *serverChannel;
00179
00180 serverChannel = (erInternalServerChannel_t *) channel;
00181 return serverChannel->sockfd;
00182 }
00183
00184 int erIpcGetMessage(erServerChannel_t channel, char *szBuffer, int *nBuf)
00185 {
00186 char szClientIP[INET_ADDRSTRLEN + 1];
00187 struct sockaddr_in clientAdr;
00188 socklen_t len;
00189 int sockfd;
00190 erInternalServerChannel_t *serverChannel;
00191 int nBufsize;
00192 int n;
00193
00194 nBufsize = *nBuf;
00195 serverChannel = (erInternalServerChannel_t *) channel;
00196 sockfd = serverChannel->sockfd;
00197
00198
00199 len = sizeof(clientAdr);
00200 n = recvfrom(sockfd, szBuffer, nBufsize, 0, (struct sockaddr *) &clientAdr, &len);
00201 szBuffer[n] = '\0';
00202
00203
00204 if (inet_ntop(AF_INET, &clientAdr.sin_addr, szClientIP, sizeof(szClientIP)))
00205 {
00206 ERIPC_LOGPRINTF("Message %s received from %s", szBuffer, szClientIP);
00207 }
00208 *nBuf = n;
00209 return 0;
00210 }
00211
00212
00213 int erIpcStartClient(int channelIdx, erClientChannel_t * channel)
00214 {
00215 erInternalClientChannel_t *clientChannel;
00216 int port;
00217 int ret;
00218 struct in_addr destinationAdr;
00219
00220
00221
00222
00223 char szDestination[] = "127.0.0.1";
00224 int sockfd;
00225 struct sockaddr_in serverAdr;
00226
00227 clientChannel = (erInternalClientChannel_t *) malloc(sizeof(erInternalClientChannel_t));
00228
00229 if (clientChannel != NULL)
00230 {
00231 *channel = (erClientChannel_t) clientChannel;
00232 }
00233 else
00234 {
00235 ERIPC_ERRORPRINTF("Out of memory.");
00236 return -1;
00237 }
00238 clientChannel->sockfd = -1;
00239
00240 if ((ret = inet_pton(AF_INET, szDestination, &destinationAdr)) == 1)
00241 {
00242 ERIPC_LOGPRINTF("Sending messages to %s", szDestination);
00243 }
00244 else if (ret == 0)
00245 {
00246 ERIPC_WARNPRINTF("%s not a presentation IP address (not in dotted decimal format)", szDestination);
00247 return -1;
00248 }
00249 else
00250 {
00251 ERIPC_WARNPRINTF("Failed to convert to a numeric IP address");
00252 return -2;
00253 }
00254
00255 port = erIpcGetServerPort(channelIdx);
00256 if (port == ER_IPC_PORT_ILLEGAL)
00257 {
00258 ERIPC_ERRORPRINTF("Could not allocate channel %d", channelIdx);
00259 return -1;
00260 }
00261
00262
00263 sockfd = socket(AF_INET, SOCK_DGRAM, 0);
00264 bzero(&serverAdr, sizeof(serverAdr));
00265 serverAdr.sin_family = AF_INET;
00266 serverAdr.sin_addr.s_addr = destinationAdr.s_addr;
00267 serverAdr.sin_port = htons(port);
00268
00269 clientChannel->sockfd = sockfd;
00270 clientChannel->serverAdr = serverAdr;
00271
00272 return 0;
00273 }