Mercurial > hg > beaglert
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 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null"; 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 "kill -s 2 \`pidof ${BuildArtifactFileName}\` 2>/dev/null; sleep 0.6"; 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