#include "eripc.h"
#include "eripcprivate.h"
#include "eripcports.h"
#include "eripcclient.h"
#include "eripclog.h"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
Go to the source code of this file.
Functions | |
int | erIpcGetVersion () |
int | erIpcInitServer (int channelIdx, int *sockfd, int local) |
int | erIpcStartServer (int channelIdx, erMessageCB callback, char *szBuffer, int *nBuf, void *data) |
int | erIpcOpenServerChannel (int channelIdx, erServerChannel_t *channel) |
int | erIpcGetServerFd (erServerChannel_t channel) |
int | erIpcGetMessage (erServerChannel_t channel, char *szBuffer, int *nBuf) |
int | erIpcStartClient (int channelIdx, erClientChannel_t *channel) |
int erIpcGetMessage | ( | erServerChannel_t | channel, | |
char * | szBuffer, | |||
int * | nBuf | |||
) |
Get a message from the channel, will block when no message is available
Cf. erIpcOpenServerChannel
channel | Communication channel | |
szBuffer | Buffer that will be used by callback | |
nBuf | size of szBuffer |
Definition at line 184 of file eripc.c.
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 // Blocking call. 00199 len = sizeof(clientAdr); 00200 n = recvfrom(sockfd, szBuffer, nBufsize, 0, (struct sockaddr *) &clientAdr, &len); 00201 szBuffer[n] = '\0'; 00202 // Who's sending this message? 00203 // clientAdr.sin_addr.s_addr // 32-bit IPv4 address, network byte ordered. 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 }
int erIpcGetServerFd | ( | erServerChannel_t | channel | ) |
Fetch the filedescriptor associated with the channel
Cf. erIpcOpenServerChannel
channel | Communication channel |
Definition at line 176 of file eripc.c.
00177 { 00178 erInternalServerChannel_t *serverChannel; 00179 00180 serverChannel = (erInternalServerChannel_t *) channel; 00181 return serverChannel->sockfd; 00182 }
int erIpcGetVersion | ( | ) |
int erIpcInitServer | ( | int | channelIdx, | |
int * | sockfd, | |||
int | local | |||
) |
Initializes the server. Only use this function when you don't want a dedicated thread for IPC handling.
channelIdx | Communication channel identifier | |
sockfd | The socket filedescriptor | |
local | Set to 1 if only local addresses need to be served |
Definition at line 48 of file eripc.c.
00049 { 00050 int error; 00051 int port; 00052 struct sockaddr_in serverAdr; 00053 int on = 1; 00054 00055 // test code 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 // NOTE : 00076 // Setting the address to INADDR_LOOPBACK will only allow processes running 00077 // on the same host to send messages to the displayMgrServer 00078 // Setting the address to INADDR_ANY will allow a process on any host to 00079 // send messages to the displayMgrServer 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 }
int erIpcOpenServerChannel | ( | int | channelIdx, | |
erServerChannel_t * | channel | |||
) |
Create the server side of the IPC communication channel.
After calling this function. Use erIpcGetServerFd() to fetch the filedescriptor associated with this channel. Monitor the filedescriptor for data. When data is available use erIpcGetMessage to fetch the data.
channelIdx | Communication channel identifier | |
channel | Opaque datastructure that contains info on communication channel |
Definition at line 147 of file eripc.c.
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 }
int erIpcStartClient | ( | int | channelIdx, | |
erClientChannel_t * | channel | |||
) |
Start the client side of the IPC communication channel
channelIdx | Communication channel identifier | |
channel | Opaque datastructure that contains info on communication channel |
Definition at line 213 of file eripc.c.
00214 { 00215 erInternalClientChannel_t *clientChannel; 00216 int port; 00217 int ret; 00218 struct in_addr destinationAdr; 00219 00220 // Note. The following variable can be turned into an argument later 00221 // INADDR_LOOPBACK : "127.0.0.1" 00222 // INADDR_ANY : "0.0.0.0" 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 }
int erIpcStartServer | ( | int | channelIdx, | |
erMessageCB | callback, | |||
char * | szBuffer, | |||
int * | nBuf, | |||
void * | data | |||
) |
Start the server side of the IPC communication channel. Under normal circumstances this function will not return. It invokes a callback when a message is received. It requires its own thread and is the easiest way to establish the server side. Note: Use erIpcOpenServerChannel(), erIpcGetServerFd() and * erIpcGetMessage() if you don't want to create a server specific thread.
channelIdx | Communication channel identifier | |
callback | Will be called when a message is received | |
szBuffer | Buffer that will be used by callback | |
nBuf | size of szBuffer | |
data | pointer to opaque datastructure. |
Definition at line 108 of file eripc.c.
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 // Blocking call. 00133 len = sizeof(clientAdr); 00134 n = recvfrom(sockfd, szBuffer, nBufsize, 0, (struct sockaddr *) &clientAdr, &len); 00135 szBuffer[n] = '\0'; 00136 // Who's sending this message? 00137 // clientAdr.sin_addr.s_addr // 32-bit IPv4 address, network byte ordered. 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 }