giuliomoro@24: ///* UDP client in the internet domain */
giuliomoro@24: 
giuliomoro@24: #include <ctype.h>
giuliomoro@24: #include <sys/time.h>
giuliomoro@24: #include <fcntl.h>
giuliomoro@24: #include "../include/client.h"
giuliomoro@24: #include <unistd.h>
giuliomoro@24: #include <rtdk.h>
giuliomoro@24: 
giuliomoro@24: #define BUFF_LEN 1024
giuliomoro@32: #define MAX_VAR_STRING 20
giuliomoro@24: 
giuliomoro@24: struct sockaddr_in outServer, inServer;
giuliomoro@24: int outSock, inSock, n, length;
giuliomoro@24: socklen_t fromlen;
giuliomoro@24: struct sockaddr_in from;
giuliomoro@24: char inBuffer[1024];
giuliomoro@24: char variableString[MAX_VAR_STRING];
giuliomoro@24: 
giuliomoro@24: int setupSockets(int receivePort, int transmitPort, char const*serverName){
giuliomoro@24: 	//setup transmitter
giuliomoro@24: 	printf("receivePort: %d; transmitPort: %d; serverName: %s\n",receivePort, transmitPort, serverName);
giuliomoro@24: 	outSock= socket(AF_INET, SOCK_DGRAM, 0);
giuliomoro@24: 	outServer.sin_port = htons(transmitPort);
giuliomoro@24: 	if (outSock < 0){
giuliomoro@24: 		error("Opening out socket");
giuliomoro@24: 		return -1;
giuliomoro@24: 	}
giuliomoro@24: 	outServer.sin_family = AF_INET;
giuliomoro@24: 	inet_pton(AF_INET,serverName,&outServer.sin_addr);
giuliomoro@24: 
giuliomoro@24: 	//setup receiver
giuliomoro@24: 	inSock=socket(AF_INET, SOCK_DGRAM, 0);
giuliomoro@24: 	if (inSock < 0){
giuliomoro@24: 		return -1;
giuliomoro@24: 		error("Opening in socket");
giuliomoro@24: 	}
giuliomoro@24: 	length = sizeof(inServer);
giuliomoro@24: 	inServer.sin_family=AF_INET;
giuliomoro@24: 	inServer.sin_addr.s_addr=INADDR_ANY;
giuliomoro@24: 	inServer.sin_port=htons(receivePort);
giuliomoro@24: 	if (bind(inSock,(struct sockaddr *)&inServer,length)<0)
giuliomoro@24: 	   error("binding");
giuliomoro@24: 	fromlen = sizeof(struct sockaddr_in);
giuliomoro@24: 	return 0;
giuliomoro@24: }
giuliomoro@24: int sendMessage(networkData message)
giuliomoro@24: {
giuliomoro@24:    unsigned int length;
giuliomoro@24:    char buffer[BUFF_LEN];
giuliomoro@24:    length=sizeof(struct sockaddr_in);
giuliomoro@24:    int k=0;
giuliomoro@24:    k=sprintf(buffer+k, "%8d;",*message.counter);
giuliomoro@24:    for(int j=0; j<message.numVariables; j++){
giuliomoro@24: 	   k+=sprintf(buffer+k, "%.3f;",*message.variables[j]);
giuliomoro@24: 	   if(k>BUFF_LEN - 20) //safety margin
giuliomoro@24: 		   continue;
giuliomoro@24:    }
giuliomoro@24:    sprintf(buffer+k,"\n");
giuliomoro@24:   // printf(buffer);
giuliomoro@24:    n=sendto(outSock,buffer,
giuliomoro@24:             strlen(buffer),0,(const struct sockaddr *)&outServer,length);
giuliomoro@24:    if (n < 0) error("Sendto");
giuliomoro@24:    return 0;
giuliomoro@24: }
giuliomoro@24: /*
giuliomoro@24: int receiveMessage()
giuliomoro@24: {
giuliomoro@24:    int n = recvfrom(inSock,inBuffer,1024,0,(struct sockaddr *)&from,&fromlen);
giuliomoro@24:    if (n < 0) error("recvfrom");
giuliomoro@24:    printf("Received a datagram: ");
giuliomoro@24:    printf(inBuffer);
giuliomoro@24:  }
giuliomoro@24: */
giuliomoro@24: 
giuliomoro@24: 
giuliomoro@24: int receiveMessage(networkData message){
giuliomoro@24: 	struct timeval stTimeOut;
giuliomoro@24: 	fd_set stReadFDS;
giuliomoro@24: 	FD_ZERO(&stReadFDS);
giuliomoro@24: 	// Timeout of one second
giuliomoro@24: 	stTimeOut.tv_sec = 0;
giuliomoro@25: 	stTimeOut.tv_usec = 0;
giuliomoro@24: 	FD_SET(inSock, &stReadFDS);
giuliomoro@24: 
giuliomoro@24: 	int t = select(inSock+1, &stReadFDS, NULL, NULL, &stTimeOut);
giuliomoro@24: 	if (t == -1) {
giuliomoro@24: 		rt_fprintf(stderr, "Call to select() failed");
giuliomoro@24: 		return -1;
giuliomoro@24: 	}
giuliomoro@24: 	else if (t != 0) {
giuliomoro@24: 		if (FD_ISSET(inSock, &stReadFDS)) {
giuliomoro@24: //			printf("There is data pending to be read..."); // Read data with recv()
giuliomoro@24: 			int n = recvfrom(inSock,inBuffer,1024,0,(struct sockaddr *)&from,&fromlen);
giuliomoro@24: 			if (n < 0){
giuliomoro@24: 				rt_fprintf(stderr,"Error while receiving");
giuliomoro@24: 				return -1;
giuliomoro@24: 			}
giuliomoro@24: 			printf("Received a datagram: ");
andrewm@45: 			printf("%s", inBuffer);
giuliomoro@24: 			//the worst parser ever
giuliomoro@24: 			int previousN=0;
giuliomoro@24: 			int currentVariable=0;
giuliomoro@25: 			for(int n=0; inBuffer[n]!=0 && currentVariable<message.numVariables && n-previousN<MAX_VAR_STRING && n<BUFF_LEN; n++){ //scan the string
giuliomoro@25: 				if(inBuffer[n]==';'||inBuffer[n]==0||inBuffer[n]=='\n'){ // if you find a separator or you are at the end of the string, parse the variable
giuliomoro@24: 					int j=0;
giuliomoro@24: 					inBuffer[n]=0;	 //set the semicolon to 0 ...
giuliomoro@25: 					while( (variableString[j++]=inBuffer[previousN++]) );; // ... so that this will stop when it gets there
giuliomoro@24: 					rt_printf("variable %d: %s\n", currentVariable, variableString);
giuliomoro@24: 					*(message.variables[currentVariable])=atof(variableString);
giuliomoro@24: 					n++; //increment to step after the semicolon
giuliomoro@24: 					previousN=n;
giuliomoro@24: 					currentVariable++;
giuliomoro@24: 				}
giuliomoro@24: 			}
giuliomoro@24: 		}
giuliomoro@24: 	}
giuliomoro@24: 	return 0;
giuliomoro@24: }
giuliomoro@24: 
giuliomoro@24: void closeSockets(){
giuliomoro@24:    close(outSock);
giuliomoro@24:    close(inSock);
giuliomoro@24: }
giuliomoro@24: void error(const char *msg)
giuliomoro@24: {
giuliomoro@24:     perror(msg);
giuliomoro@24:     exit(0);
giuliomoro@24: }