view core/client.cpp @ 68:59edd5780fef

Changed d-box code to run cleanly when built on board. Updated Makefile to add ne10 include path on board. Some extra docs in Utilities.h
author andrewm
date Fri, 17 Jul 2015 16:57:08 +0100
parents 579c86316008
children f3251851c718
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("%s", 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);
}