changeset 108:3068421c0737 ultra-staging

Merged default into ultra-staging
author Giulio Moro <giuliomoro@yahoo.it>
date Tue, 18 Aug 2015 00:35:15 +0100
parents d3f869b98147 (diff) 836052c86e1e (current diff)
children 7b351b7d8770
files .cproject core/PRU.cpp core/RTAudio.cpp core/UdpClient.cpp include/PRU.h include/RTAudio.h include/RTAudioSettings.h include/UdpClient.h include/render.h projects/basic_network/render.cpp projects/basic_sensor/main.cpp projects/basic_sensor/render.cpp pru_rtaudio.bin
diffstat 10 files changed, 585 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/.cproject	Tue Aug 18 00:13:04 2015 +0100
+++ b/.cproject	Tue Aug 18 00:35:15 2015 +0100
@@ -114,7 +114,7 @@
 				</extensions>
 			</storageModule>
 			<storageModule moduleId="cdtBuildSystem" version="4.0.0">
-				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1521194538" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" postannouncebuildStep="Stopping process on BBB and copying new binary" postbuildStep="ssh root@192.168.7.2 &quot;kill -s 2 \`pidof ${BuildArtifactFileName}\` 2&gt;/dev/null&quot;; scp ${BuildArtifactFilePrefix}${BuildArtifactFileName} root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall">
+				<configuration artifactName="${ProjName}" buildArtefactType="org.eclipse.cdt.build.core.buildArtefactType.exe" buildProperties="org.eclipse.cdt.build.core.buildType=org.eclipse.cdt.build.core.buildType.release,org.eclipse.cdt.build.core.buildArtefactType=org.eclipse.cdt.build.core.buildArtefactType.exe" cleanCommand="rm -rf" description="" id="cdt.managedbuild.config.gnu.exe.release.1521194538" name="Release" parent="cdt.managedbuild.config.gnu.exe.release" postannouncebuildStep="Stopping process on BBB and copying new binary" postbuildStep="ssh root@192.168.7.2 &quot;kill -s 2 \`pidof ${BuildArtifactFileName}\` 2&gt;/dev/null; sleep 0.6&quot;; scp ${BuildArtifactFilePrefix}${BuildArtifactFileName} root@192.168.7.2:~/beaglert/ ; echo 'done copying' | wall">
 					<folderInfo id="cdt.managedbuild.config.gnu.exe.release.1521194538." name="/" resourcePath="">
 						<toolChain id="cdt.managedbuild.toolchain.gnu.exe.release.1612059942" name="Linux GCC" superClass="cdt.managedbuild.toolchain.gnu.exe.release">
 							<targetPlatform id="cdt.managedbuild.target.gnu.platform.exe.release.908983575" name="Debug Platform" superClass="cdt.managedbuild.target.gnu.platform.exe.release"/>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/UdpServer.cpp	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,88 @@
+/*
+ * udpServer.cpp
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+#include "../include/UdpServer.h"
+
+UdpServer::UdpServer(int aPort){
+	init(aPort);
+};
+UdpServer::UdpServer(){
+	init(0);
+}
+UdpServer::~UdpServer(){
+	//TODO: unbind from port. AFAIK, this involves closing the socket, therefore creating the socket should become part of bindToPort
+};
+bool UdpServer::init(int aPort){
+	enabled=true;
+	stTimeOut.tv_sec = 0; //set timeout to 0
+	stTimeOut.tv_usec = 0;
+	inSocket=socket(AF_INET, SOCK_DGRAM, 0);
+	if (inSocket < 0){
+		enabled=false;
+	}
+	length = sizeof(server);
+	server.sin_family=AF_INET;
+	server.sin_addr.s_addr=INADDR_ANY;
+	enabled=bindToPort(aPort);
+	wasteBufferSize=2048;
+	wasteBuffer=malloc(wasteBufferSize);
+	return enabled;
+}
+
+bool UdpServer::bindToPort(int aPort){
+	port=aPort;
+	if(port<1){
+		enabled=false;
+		return false;
+	}
+	server.sin_port=htons(port);
+	if (bind(inSocket,(struct sockaddr *)&server,length)<0){
+		enabled=false;
+		return false;
+	}
+	enabled=true;
+	return true;
+};
+int UdpServer::read(//Returns the number of bytes read, or -1 if there was an error.
+					void *destBuffer,
+					int maxBytesToRead){
+	if(enabled==false)
+		return -1;
+	FD_ZERO(&stReadFDS);
+	FD_SET(inSocket, &stReadFDS);
+	int descriptorReady= select(inSocket+1, &stReadFDS, NULL, NULL, &stTimeOut);
+	if(descriptorReady<0){ //an error occurred
+		return -1;
+	}
+	int numberOfBytes=0;
+	if (FD_ISSET(inSocket, &stReadFDS)) {
+		numberOfBytes=recvfrom(inSocket,destBuffer,maxBytesToRead,0,(struct sockaddr *)&from,&fromLength);
+		if(numberOfBytes<0)
+			return -1;
+	}
+	return numberOfBytes;
+};
+int UdpServer::emptySocket(){
+	return emptySocket(0);
+}
+int UdpServer::emptySocket(int maxBytes){//discards up to maxBytes from the socket. Returns the number of bytes discarded.
+	if(wasteBuffer==NULL)
+		return -1;
+	int numberOfBytes=0;
+	while(int n=read(wasteBuffer, wasteBufferSize)){// calls the read function until it does not return any more bytes (i.e.: socket is empty)
+		if(n>0)
+			numberOfBytes+=n;
+		if(n<0)
+			return -1;
+		if(maxBytes>0 && numberOfBytes>=maxBytes)
+			break;
+	};
+	return numberOfBytes;
+}
+void* UdpServer::getWaste(){ //returns the last datagram retrieved by emptySocket()
+	return wasteBuffer;
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/client.cpp	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,131 @@
+///* 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 MESSAGE_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[MESSAGE_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>MESSAGE_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 sendAudio(networkAudio *audio)
+{
+   unsigned int length;
+   length=sizeof(struct sockaddr_in);
+//   for(int k=0; k<NETWORK_AU	DIO_BUFFER_SIZE; k++)
+//	   printf("%f\n",audio.buffers[!audio.currentBuffer][k]);
+   n=sendto(outSock,audio->buffers[!audio->currentBuffer],NETWORK_AUDIO_BUFFER_SIZE*sizeof(float),0,(const struct sockaddr *)&outServer,length);
+   if (n < 0) error("Sendto");
+   audio->doneOnTime=1;
+   return 0;
+}
+
+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<MESSAGE_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);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/core/intervals.cpp	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,94 @@
+/*
+ * intervals.h
+ *
+ *  Created on: 18 May 2015
+ *      Author: unmanaged
+ */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <native/timer.h>
+#include <rtdk.h>
+
+#include "../include/intervals.h"
+void Interval::init(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName){
+	enabled=false;
+	numAverages=aNumAverages;
+	intervals=(RTIME *)malloc(sizeof(RTIME)*numAverages);
+	samplingRate=aSamplingRate;
+	numFrames=aNumFrames;
+	maxTimeus=0;
+	intervalsPointer=0;
+	sum=0;
+	startTime=0;
+
+	if(intervals!=0)
+		enabled=true;
+	int len=strlen(aName);
+	name=(char *)malloc(sizeof(char)*(len+1));
+	strcpy(name, aName);
+	if(name == 0)
+		enabled=false;
+};
+Interval::Interval(){
+	init(100,1,44100,"");
+}
+Interval::Interval(int aNumAverages){
+	init(aNumAverages,1,44100,"");
+}
+Interval::Interval(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName){
+	init(aNumAverages,aNumFrames,aSamplingRate,aName);
+}
+Interval::~Interval(){
+	free(intervals);
+//			free(name);
+}
+void Interval::setNumFrames(int aNumFrames){
+	numFrames=aNumFrames;
+};
+
+int Interval::start(){
+//	printf("start: intervals: 0x%x, intervalsPointer: %d, numAverages: %d\n", intervals,intervalsPointer,numAverages);
+	if(!enabled)
+		return 0;
+	startTime=rt_timer_read();
+	return 1;
+}
+int Interval::resetMax(){
+	maxTimeus=0;
+	return 1;
+}
+int Interval::split(){ //updates
+	if(!enabled)
+		return 0;
+	int currentInterval=rt_timer_read()-startTime;
+	RTIME *currentPointer=&(intervals[intervalsPointer]);
+	sum-=*currentPointer; //take out the oldest value from the sum
+	*currentPointer=currentInterval;
+	sum+=*currentPointer; //add the new value to the sum
+	timeus=((float)sum)/numAverages/1000.0;
+	maxTimeus=timeus>maxTimeus?timeus:maxTimeus;
+	intervalsPointer++;
+	if(intervalsPointer>=(numAverages-1)){
+		intervalsPointer=0;
+	}
+	return 1;
+}
+void Interval::setEnabled(bool aActive){
+	enabled=aActive;
+}
+float Interval::getTimeus(){
+	return timeus;
+}
+float Interval::getMaxTimeus(){
+	return maxTimeus;
+}
+void Interval::print(){
+	rt_printf(//"sleepTimer time: 29.484us, (1.30 samples, numFrames: 2, 65.01%%). MaxTime: 30.439us, (1.34 samples, 67.12%%)\n");
+"%s time: %.3fus, (%.2f samples, numFrames: %d, %.2f%%). MaxTime: %.3fus, (%.2f samples, %.2f%%)\n",
+			name,
+			timeus, timeus/1000000.0*samplingRate, numFrames, timeus/1000000.0*samplingRate/numFrames * 100,
+			maxTimeus, maxTimeus/1000000.0*samplingRate, maxTimeus/1000000.0*samplingRate/numFrames * 100);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/UdpServer.h	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,51 @@
+/*
+ * udpServer.h
+ *
+ *  Created on: 19 May 2015
+ *      Author: giulio moro
+ */
+
+#ifndef UDPSERVER_H_
+#define UDPSERVER_H_
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+class UdpServer{
+	private:
+		int port;
+		int enabled;
+		int inSocket;
+		struct sockaddr_in server;
+		struct timeval stTimeOut;
+		fd_set stReadFDS;
+		int size;
+		void *wasteBuffer;
+		int wasteBufferSize;
+		int length;
+		socklen_t fromLength;
+		struct sockaddr_in from;
+	public:
+		UdpServer();
+		UdpServer(int aPort);
+		~UdpServer();
+		bool init(int aPort);
+		bool bindToPort(int aPort);
+		int getBoundPort() const;
+		int read(void *destBuffer,
+				int maxBytesToRead);
+		int emptySocket();
+		int emptySocket(int maxBytes);
+		void *getWaste();
+};
+
+
+
+#endif /* UDPSERVER_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/client.h	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,33 @@
+/* UDP client in the internet domain */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+
+struct networkData{
+	int *counter;
+	float *variables[16];
+	int numVariables;
+};
+#define NETWORK_AUDIO_BUFFER_SIZE 100 //1400/4 //maximum payload for a UDP datagram over ethernet is 1472 bytes, I leave some headroom and divide by 4 to get the number of floats
+struct networkAudio{
+	int timestamp;
+	int currentBuffer;
+	int index;
+	float buffers[2][NETWORK_AUDIO_BUFFER_SIZE];
+	int doneOnTime;
+	bool toBeSent;
+	UdpClient udpClient;
+};
+
+void error(const char *);
+int setupSockets(int receivePort, int transmitPort, char const*serverName);
+int sendMessage(networkData message);
+int sendAudio(networkAudio *audio);
+int receiveMessage(networkData message);
+void closeSockets();
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/include/intervals.h	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,50 @@
+/*
+ * intervals.h
+ *
+ *  Created on: 18 May 2015
+ *      Author: unmanaged
+ */
+
+#ifndef INTERVALS_H_
+#define INTERVALS_H_
+
+#define TEN_POW_9 1000000000
+
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <native/timer.h>
+#include <rtdk.h>
+
+class Interval
+{
+	private:
+		int intervalsPointer;
+		long sum;
+		RTIME startTime;
+		RTIME *intervals;
+		float maxTimeus;
+		float timeus;
+		float samplingRate; //used for getPrint()
+		int numFrames;
+		bool enabled; //whether it actually reads the clock or not
+		int numAverages;
+		char *name;
+		void init(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName);
+	public:
+		Interval();
+		Interval(int aNumAverages);
+		Interval(int aNumAverages, int aNumFrames, float aSamplingRate, const char *aName);
+		~Interval();
+		void setNumFrames(int aNumFrames);
+		int start();
+		int resetMax();
+		int split();
+		void setEnabled(bool aActive);
+		float getTimeus();
+		float getMaxTimeus();
+		void print();
+};
+
+#endif /* INTERVALS_H_ */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/tests/UdpClientUdpServerTest.cpp	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,128 @@
+#include "../../include/UdpServer.h"
+#include "../../include/UdpClient.h"
+#include <unistd.h>
+
+int test1(UdpServer *server, UdpClient *client){
+	int buffer;
+	int tot=100;
+	int errors=0;
+	for(int n=0; n<tot; n++){
+		if(client->send(&n,sizeof(int))!=1){
+			printf("error: while sending\n");
+			errors++;
+		}
+	}
+	for(int n=0; n<tot; n++){
+		if(server->read(&buffer,sizeof(int))<0){
+			printf("error: unable to read\n");
+			errors++;
+			continue;
+		};
+		if(n!=buffer){
+			printf("error: %d!=%d\n",n,buffer);
+			errors++;
+		}
+	}
+	int n=server->emptySocket();
+	if(n!=0)
+		printf("Error: the socket had %d bytes\n",n);
+	return errors;
+}
+int compareStrings(char * str1, char * str2){
+	if(strlen(str1)!=strlen(str2))
+		return -1;
+	for(int n=0; n<strlen(str1); n++){
+		if(str1[n]!=str2[n])
+			return -1;
+	}
+	return 0;
+}
+
+int test2(UdpServer *server, UdpClient *client){
+	char buffer[1000];
+	int tot=100;
+	int errors=0;
+	for(int n=0; n<tot; n++){
+		int num=sprintf(buffer,"%08.8f",n/1000.0);
+		client->send(&buffer,sizeof(char)*(num+1));
+	}
+	char auxBuffer[100];
+	for(int n=0; n<tot; n++){
+		int num=sprintf(auxBuffer,"%08.8f",n/1000.0);
+		server->read(&buffer,num*sizeof(char));
+		if(compareStrings(auxBuffer,buffer)==-1){
+			printf("error: %s!=%s\n",auxBuffer,buffer);
+			errors++;
+		}
+	}
+
+	return errors;
+}
+
+int test3(UdpServer *server, UdpClient *client){
+	char buffer[1000];
+	int tot=100;
+	int errors=0;
+    int totNum=0;
+	for(int n=0; n<tot; n++){
+		int num=sprintf(buffer,"%.8f",n/1000.0);
+		client->send(&buffer,sizeof(char)*(num+1));
+        totNum+=1+num;
+	}
+    int n=server->emptySocket();
+    if(n!=totNum){
+        errors=1;
+        printf("retrieved bytes differs from sent bytes: %d!=%d\n",n,totNum);
+    }
+	return errors;
+}
+
+
+int main(){
+	int port=1234;
+	char serverName[]="127.0.0.1";
+	UdpServer server(port);
+	UdpClient client(port,serverName);
+	int errors=0;
+	int ret=0;
+	ret=test1(&server,&client);
+	errors+=ret;
+	if(ret)
+		printf("test1 failed with %d errors\n", ret);
+	else
+		printf("test1 passed\n");
+
+	ret=test2(&server,&client);
+	errors+=ret;
+	if(ret)
+		printf("test2 failed with %d errors\n", ret);
+	else
+		printf("test2 passed\n");
+
+	ret=test3(&server,&client);
+	errors+=ret;
+	if(ret)
+		printf("test3 failed with %d errors\n", ret);
+	else
+		printf("test3 passed\n");
+//now test if the setPort and setServer methods work
+	client.~UdpClient();
+	server.~UdpServer();
+	port=1235;
+	UdpServer server1;
+	UdpClient client1;
+	client1.setPort(port);
+	client1.setServer(serverName);
+	if(server1.bindToPort(port)==false){
+		printf("unable to bind to port %d\n",port);
+		errors+=1;
+	}
+	ret=test1(&server1, &client1);
+	errors+=ret;
+	if(ret)
+		printf("test1 failed with %d errors\n", ret);
+	else
+		printf("test1 passed\n");
+
+	return errors;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/tests/make_tests.sh	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,7 @@
+#!/bin/bash
+mkdir -p build
+mkdir -p bin
+g++ -o build/UdpServer.o -O2 -c ../../core/UdpServer.cpp &&\
+g++ -O2 -o build/UdpClient.o -c ../../core/UdpClient.cpp && \
+g++ -O2 -o build/UdpClientUdpServerTest.o -c UdpClientUdpServerTest.cpp && \
+g++ -o bin/UdpClientUdpServerTest build/UdpClientUdpServerTest.o build/UdpClient.o build/UdpServer.o 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/resources/tests/run_tests.sh	Tue Aug 18 00:35:15 2015 +0100
@@ -0,0 +1,2 @@
+#!/bin/bash
+bin/*