view core/client.cpp @ 39:638bc1ae2500 staging

Improved readibility of the DIGITAL code in the PRU, using register names instead of aliases and expanding some of the macros, removing unused macros. Binaries were not modified
author Giulio Moro <giuliomoro@yahoo.it>
date Wed, 13 May 2015 12:18:10 +0100
parents 12ee9a61e81d
children 4255ecbb9bec 579c86316008
line wrap: on
line source
///* UDP client in the internet domain */

#include <ctype.h>
#include <sys/time.h>
#include <fcntl.h>
#include "../include/client.h"
#include <unistd.h>
#include <rtdk.h>

#define BUFF_LEN 1024
#define MAX_VAR_STRING 20

struct sockaddr_in outServer, inServer;
int outSock, inSock, n, length;
socklen_t fromlen;
struct sockaddr_in from;
char inBuffer[1024];
char variableString[MAX_VAR_STRING];

int setupSockets(int receivePort, int transmitPort, char const*serverName){
	//setup transmitter
	printf("receivePort: %d; transmitPort: %d; serverName: %s\n",receivePort, transmitPort, serverName);
	outSock= socket(AF_INET, SOCK_DGRAM, 0);
	outServer.sin_port = htons(transmitPort);
	if (outSock < 0){
		error("Opening out socket");
		return -1;
	}
	outServer.sin_family = AF_INET;
	inet_pton(AF_INET,serverName,&outServer.sin_addr);

	//setup receiver
	inSock=socket(AF_INET, SOCK_DGRAM, 0);
	if (inSock < 0){
		return -1;
		error("Opening in socket");
	}
	length = sizeof(inServer);
	inServer.sin_family=AF_INET;
	inServer.sin_addr.s_addr=INADDR_ANY;
	inServer.sin_port=htons(receivePort);
	if (bind(inSock,(struct sockaddr *)&inServer,length)<0)
	   error("binding");
	fromlen = sizeof(struct sockaddr_in);
	return 0;
}
int sendMessage(networkData message)
{
   unsigned int length;
   char buffer[BUFF_LEN];
   length=sizeof(struct sockaddr_in);
   int k=0;
   k=sprintf(buffer+k, "%8d;",*message.counter);
   for(int j=0; j<message.numVariables; j++){
	   k+=sprintf(buffer+k, "%.3f;",*message.variables[j]);
	   if(k>BUFF_LEN - 20) //safety margin
		   continue;
   }
   sprintf(buffer+k,"\n");
  // printf(buffer);
   n=sendto(outSock,buffer,
            strlen(buffer),0,(const struct sockaddr *)&outServer,length);
   if (n < 0) error("Sendto");
   return 0;
}
/*
int receiveMessage()
{
   int n = recvfrom(inSock,inBuffer,1024,0,(struct sockaddr *)&from,&fromlen);
   if (n < 0) error("recvfrom");
   printf("Received a datagram: ");
   printf(inBuffer);
 }
*/


int receiveMessage(networkData message){
	struct timeval stTimeOut;
	fd_set stReadFDS;
	FD_ZERO(&stReadFDS);
	// Timeout of one second
	stTimeOut.tv_sec = 0;
	stTimeOut.tv_usec = 0;
	FD_SET(inSock, &stReadFDS);

	int t = select(inSock+1, &stReadFDS, NULL, NULL, &stTimeOut);
	if (t == -1) {
		rt_fprintf(stderr, "Call to select() failed");
		return -1;
	}
	else if (t != 0) {
		if (FD_ISSET(inSock, &stReadFDS)) {
//			printf("There is data pending to be read..."); // Read data with recv()
			int n = recvfrom(inSock,inBuffer,1024,0,(struct sockaddr *)&from,&fromlen);
			if (n < 0){
				rt_fprintf(stderr,"Error while receiving");
				return -1;
			}
			printf("Received a datagram: ");
			printf(inBuffer);
			//the worst parser ever
			int previousN=0;
			int currentVariable=0;
			for(int n=0; inBuffer[n]!=0 && currentVariable<message.numVariables && n-previousN<MAX_VAR_STRING && n<BUFF_LEN; n++){ //scan the string
				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
					int j=0;
					inBuffer[n]=0;	 //set the semicolon to 0 ...
					while( (variableString[j++]=inBuffer[previousN++]) );; // ... so that this will stop when it gets there
					rt_printf("variable %d: %s\n", currentVariable, variableString);
					*(message.variables[currentVariable])=atof(variableString);
					n++; //increment to step after the semicolon
					previousN=n;
					currentVariable++;
				}
			}
		}
	}
	return 0;
}

void closeSockets(){
   close(outSock);
   close(inSock);
}
void error(const char *msg)
{
    perror(msg);
    exit(0);
}