Mercurial > hg > beaglert
changeset 34:46d87f680da5 matrix_gpio
Merged bbb_network and the so-called "matrix_gpio" branches
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Mon, 11 May 2015 19:50:48 +0100 |
parents | 83baffda5786 (current diff) 12ee9a61e81d (diff) |
children | 46571f8f04a1 006a8500863f |
files | .cproject core/RTAudioCommandLine.cpp |
diffstat | 16 files changed, 611 insertions(+), 37 deletions(-) [+] |
line wrap: on
line diff
--- a/.cproject Mon May 11 18:58:47 2015 +0100 +++ b/.cproject Mon May 11 19:50:48 2015 +0100 @@ -92,7 +92,7 @@ <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/analogDigitalDemo"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic_network"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration> @@ -177,7 +177,7 @@ <sourceEntries> <entry excluding="audio_routines_old.S" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="core"/> <entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="include"/> - <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/analogDigitalDemo"/> + <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="projects/basic_network"/> <entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="source"/> </sourceEntries> </configuration>
--- a/core/RTAudio.cpp Mon May 11 18:58:47 2015 +0100 +++ b/core/RTAudio.cpp Mon May 11 19:50:48 2015 +0100 @@ -31,6 +31,7 @@ #include "../include/I2c_Codec.h" #include "../include/render.h" #include "../include/GPIOcontrol.h" +#include "../include/client.h" using namespace std; @@ -81,6 +82,7 @@ // // Returns 0 on success. + int BeagleRT_initAudio(RTAudioSettings *settings, void *userData) { rt_print_auto_init(1); @@ -184,7 +186,7 @@ settings->useAnalog ? settings->periodSize : 0, /* analog period size */ audioPeriodSize, analogSampleRate, audioSampleRate, - userData)) { + userData, settings)) { cout << "Couldn't initialise audio rendering\n"; return 1; }
--- a/core/RTAudioCommandLine.cpp Mon May 11 18:58:47 2015 +0100 +++ b/core/RTAudioCommandLine.cpp Mon May 11 19:50:48 2015 +0100 @@ -10,8 +10,9 @@ #include <cstring> #include <getopt.h> #include "../include/RTAudio.h" + #ifndef OPT_PRU_FILE -#define OPT_PRU_FILE 176 +#define OPT_PRU_FILE 176 // this is an extended ascii code #endif // Default command-line options for RTAudio @@ -27,10 +28,14 @@ {"dac-level", 1, NULL, 'D'}, {"adc-level", 1, NULL, 'A'}, {"hp-level", 1, NULL, 'H'}, + {"receive-port", 1, NULL, 'r'}, + {"transmit-port", 1, NULL, 't'}, + {"server-name",1,NULL,'s'}, {"pru-file",1,NULL,OPT_PRU_FILE}, {NULL, 0, NULL, 0} }; -const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:g:G:"; + +const char gDefaultShortOptions[] = "p:vm:M:C:D:A:H:g:G:r:t:s:"; // This function sets the default settings for the RTAudioSettings structure void BeagleRT_defaultSettings(RTAudioSettings *settings) @@ -48,6 +53,9 @@ settings->verbose = 0; settings->pruFilename[0]='\0'; settings->codecI2CAddress = CODEC_I2C_ADDRESS; + settings->receivePort=9998; + settings->transmitPort=9999; + strcpy(settings->serverName, "127.0.0.1"); settings->ampMutePin = kAmplifierMutePin; } @@ -167,6 +175,19 @@ case 'H': settings->headphoneLevel = atof(optarg); break; + case 'r': + settings->receivePort = atoi(optarg); + break; + case 't': + settings->transmitPort = atoi(optarg); + break; + case 's': + if(strlen(optarg)<MAX_SERVERNAME_LENGTH) + strcpy(settings->serverName, optarg); + else + std::cerr << "Warning: server name is too long (>" << MAX_SERVERNAME_LENGTH << " characters)." + " Using default severName Instead ( " << settings->serverName << " ).\n"; + break; case OPT_PRU_FILE: if(strlen(optarg)<MAX_PRU_FILENAME_LENGTH) strcpy(settings->pruFilename, optarg); @@ -190,9 +211,13 @@ std::cerr << " --hp-level [-H] dBs: Set the headphone output level (0dB max; -63.5dB min)\n"; std::cerr << " --mute-speaker [-M] val: Set whether to mute the speaker initially (default: no)\n"; std::cerr << " --use-analog [-m] val: Set whether to use ADC/DAC analog (default: yes)\n"; - std::cerr << " --use-gpio-analog [-g] val: Set whether to use GPIO analog (default: yes)\n"; + std::cerr << " --use-digital [-g] val: Set whether to use digital GPIO channels (default: yes)\n"; std::cerr << " --analog-channels [-C] val: Set the number of ADC/DAC channels (default: 8)\n"; std::cerr << " --digital-channels [-G] val: Set the number of GPIO channels (default: 16)\n"; + std::cerr << " --digital-channels [-G] val: Set the number of digital GPIO channels (default: 16)\n"; + std::cerr << " --receive-port [-r] val: Set the receive port (default: 9998)\n"; + std::cerr << " --transmit-port [-t] val: Set the transmit port (default: 9999)\n"; + std::cerr << " --server-name [-s] val: Set the destination server name (default: '127.0.0.1')\n"; std::cerr << " --pru-file val: Set an optional external file to use for the PRU binary code\n"; std::cerr << " --verbose [-v]: Enable verbose logging information\n"; }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/client.cpp Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,129 @@ +///* 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); +}
--- a/include/RTAudio.h Mon May 11 18:58:47 2015 +0100 +++ b/include/RTAudio.h Mon May 11 19:50:48 2015 +0100 @@ -13,7 +13,7 @@ #ifndef RTAUDIO_H_ #define RTAUDIO_H_ - +#include "RTAudioSettings.h" #include "render.h" // Useful constants @@ -29,33 +29,11 @@ #define DEFAULT_DAC_LEVEL 0.0 #define DEFAULT_ADC_LEVEL -6.0 #define DEFAULT_HP_LEVEL -6.0 -#define MAX_PRU_FILENAME_LENGTH 256 enum { kAmplifierMutePin = 61 // P8-26 controls amplifier mute }; -// Structure which contains initialisation parameters for the -// real-time audio system -typedef struct { - // These items might be adjusted by the user: - int periodSize; // Number of (analog) frames per period; audio is twice this - int beginMuted; // Whether to begin with the speakers muted - float dacLevel; // Level for the audio DAC output - float adcLevel; // Level for the audio ADC input - float headphoneLevel; // Level for the headphone output - int useAnalog; // Whether to use the analog - int useDigital; // Whether to use the 16 programmable GPIOs - int numAnalogChannels; // How many channels for the ADC and DAC - int numDigitalChannels; // How many channels for the GPIOs - int verbose; // Whether to use verbose logging - char pruFilename[MAX_PRU_FILENAME_LENGTH]; //the external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h - // These items are hardware-dependent and should only be changed - // to run on different hardware - int codecI2CAddress; // Where the codec can be found on the I2C bus - int ampMutePin; // Pin where amplifier mute can be found -} RTAudioSettings; - typedef void* AuxiliaryTask; // Opaque data type to keep track of aux tasks // Flag that indicates when the audio will stop; can be read or
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/RTAudioSettings.h Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,40 @@ +/* + * RTaudioSettings.h + * + * Created on: 6 May 2015 + * Author: unmanaged + */ + +#ifndef RTAUDIOSETTINGS_H_ +#define RTAUDIOSETTINGS_H_ + +#define MAX_PRU_FILENAME_LENGTH 256 +#define MAX_SERVERNAME_LENGTH 256 +// Structure which contains initialisation parameters for the +// real-time audio system +typedef struct { + // These items might be adjusted by the user: + int periodSize; // Number of (analog) frames per period; audio is twice this + int beginMuted; // Whether to begin with the speakers muted + float dacLevel; // Level for the audio DAC output + float adcLevel; // Level for the audio ADC input + float headphoneLevel; // Level for the headphone output + int useAnalog; // Whether to use the analog + int useDigital; // Whether to use the 16 programmable GPIOs + int numAnalogChannels; // How many channels for the ADC and DAC + int numDigitalChannels; // How many channels for the GPIOs + int verbose; // Whether to use verbose logging + char pruFilename[MAX_PRU_FILENAME_LENGTH]; //the external .bin file to load. If empty will use PRU code from pru_rtaudio_bin.h + // These items are hardware-dependent and should only be changed + // to run on different hardware + int codecI2CAddress; // Where the codec can be found on the I2C bus + int ampMutePin; // Pin where amplifier mute can be found + int receivePort; //port where the UDP server will listen + int transmitPort; //port where the UDP client will transmit + char serverName[MAX_SERVERNAME_LENGTH]; +} RTAudioSettings; + + + + +#endif /* RTAUDIOSETTINGS_H_ */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/client.h Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,22 @@ +/* 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; +}; + +void error(const char *); +int setupSockets(int receivePort, int transmitPort, char const*serverName); +int sendMessage(networkData message); +int receiveMessage(networkData message); +void closeSockets();
--- a/include/render.h Mon May 11 18:58:47 2015 +0100 +++ b/include/render.h Mon May 11 19:50:48 2015 +0100 @@ -10,8 +10,10 @@ // uint types #include <stdint.h> -#include "../include/Utilities.h" -#include "../include/digital_gpio_mapping.h" +#include "Utilities.h" +#include "digital_gpio_mapping.h" +#include "RTAudioSettings.h" + // Mappings from pin numbers on PCB to actual DAC channels // This gives the DAC and ADC connectors the same effective pinout #define DAC_PIN0 6 @@ -41,7 +43,7 @@ int numAnalogFramesPerPeriod, int numAudioFramesPerPeriod, float analogSampleRate, float audioSampleRate, - void *userData); + void *userData, RTAudioSettings *settings); void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, float *analogIn, float *analogOut, uint32_t *digital);
--- a/projects/basic/main.cpp Mon May 11 18:58:47 2015 +0100 +++ b/projects/basic/main.cpp Mon May 11 19:50:48 2015 +0100 @@ -4,7 +4,7 @@ * Created on: Oct 24, 2014 * Author: parallels */ - +#include <unistd.h> #include <iostream> #include <cstdlib> #include <libgen.h>
--- a/projects/basic/render.cpp Mon May 11 18:58:47 2015 +0100 +++ b/projects/basic/render.cpp Mon May 11 19:50:48 2015 +0100 @@ -22,11 +22,11 @@ // // Return true on success; returning false halts the program. -bool initialise_render(int numMatrixChannels, int numAudioChannels, +bool initialise_render(int numMatrixChannels, int numDigitalChannels, int numAudioChannels, int numMatrixFramesPerPeriod, int numAudioFramesPerPeriod, float matrixSampleRate, float audioSampleRate, - void *userData) + void *userData, RTAudioSettings* settings) { // Retrieve a parameter passed in from the initAudio() call gFrequency = *(float *)userData; @@ -42,8 +42,8 @@ // ADCs and DACs (if available). If only audio is available, numMatrixFrames // will be 0. -void render(int numMatrixFrames, int numAudioFrames, float *audioIn, float *audioOut, - uint16_t *matrixIn, uint16_t *matrixOut) +void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, + float *analogIn, float *analogOut, uint32_t *digital) { for(int n = 0; n < numAudioFrames; n++) { float out = 0.8f * sinf(gPhase);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/basic_network/main.cpp Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,98 @@ +/* + * main.cpp + * + * Created on: Oct 24, 2014 + * Author: parallels + */ + +#include <iostream> +#include <cstdlib> +#include <libgen.h> +#include <signal.h> +#include <getopt.h> +#include "../../include/RTAudio.h" +#include <unistd.h> + +using namespace std; + +// Handle Ctrl-C by requesting that the audio rendering stop +void interrupt_handler(int var) +{ + gShouldStop = true; +} + +// Print usage information +void usage(const char * processName) +{ + cerr << "Usage: " << processName << " [options]" << endl; + + BeagleRT_usage(); + + cerr << " --frequency [-f] frequency: Set the frequency of the oscillator\n"; + cerr << " --help [-h]: Print this menu\n"; +} + +int main(int argc, char *argv[]) +{ + RTAudioSettings settings; // Standard audio settings + float frequency = 440.0; // Frequency of oscillator + + struct option customOptions[] = + { + {"help", 0, NULL, 'h'}, + {"frequency", 1, NULL, 'f'}, + {NULL, 0, NULL, 0} + }; + + // Set default settings + BeagleRT_defaultSettings(&settings); + + // Parse command-line arguments + while (1) { + int c; + if ((c = BeagleRT_getopt_long(argc, argv, "hf:", customOptions, &settings)) < 0) + break; + switch (c) { + case 'h': + usage(basename(argv[0])); + exit(0); + case 'f': + frequency = atof(optarg); + break; + case '?': + default: + usage(basename(argv[0])); + exit(1); + } + } + + // Initialise the PRU audio device + if(BeagleRT_initAudio(&settings, &frequency) != 0) { + cout << "Error: unable to initialise audio" << endl; + return -1; + } + + // Start the audio device running + if(BeagleRT_startAudio()) { + cout << "Error: unable to start real-time audio" << endl; + return -1; + } + + // Set up interrupt handler to catch Control-C and SIGTERM + signal(SIGINT, interrupt_handler); + signal(SIGTERM, interrupt_handler); + + // Run until told to stop + while(!gShouldStop) { + usleep(100000); + } + + // Stop the audio device + BeagleRT_stopAudio(); + + // Clean up any resources allocated for audio + BeagleRT_cleanupAudio(); + + // All done! + return 0; +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/projects/basic_network/render.cpp Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,89 @@ +/* + * render.cpp + * + * Created on: Oct 24, 2014 + * Author: parallels + */ + +#include "../../include/RTAudioSettings.h" +#include "../../include/render.h" +#include <cmath> +#include "../../include/client.h" +#include "../../include/RTAudio.h" // to schedule lower prio parallel process +#include <rtdk.h> +float gFrequency; +float gPhase; +float gInverseSampleRate; +int gCount=0; +networkData networkObject; +AuxiliaryTask transmitReceiveDataTask; + +void transmitReceiveData(){ + printf("transmitReceiveData auxiliary task has started\n"); + while(!gShouldStop){ + sendMessage(networkObject); + receiveMessage(networkObject); + usleep(1000); + } + closeSockets(); +} + +// initialise_render() is called once before the audio rendering starts. +// Use it to perform any initialisation and allocation which is dependent +// on the period size or sample rate. +// +// userData holds an opaque pointer to a data structure that was passed +// in from the call to initAudio(). +// +// Return true on success; returning false halts the program. +bool initialise_render(int numMatrixChannels, int numDigitalChannels, int numAudioChannels, + int numMatrixFramesPerPeriod, + int numAudioFramesPerPeriod, + float matrixSampleRate, float audioSampleRate, + void *userData, RTAudioSettings *settings) +{ + // Retrieve a parameter passed in from the initAudio() call + gFrequency = *(float *)userData; + + gInverseSampleRate = 1.0 / audioSampleRate; + gPhase = 0.0; + + networkObject.counter=&gCount; + networkObject.variables[0]=&gFrequency; + networkObject.variables[1]=&gPhase; + networkObject.numVariables=2; + setupSockets(settings->receivePort, settings->transmitPort, settings->serverName); + transmitReceiveDataTask=createAuxiliaryTaskLoop(*transmitReceiveData, 80, "transmit-receive-data"); + //scheduleAuxiliaryTask(transmitReceiveDataTask); //here it does not work + return true; +} + +// render() is called regularly at the highest priority by the audio engine. +// Input and output are given from the audio hardware and the other +// ADCs and DACs (if available). If only audio is available, numMatrixFrames +// will be 0. + +void render(int numAnalogFrames, int numAudioFrames, int numDigitalFrames, float *audioIn, float *audioOut, + float *analogIn, float *analogOut, uint32_t *digital) +{ + for(int n = 0; n < numAudioFrames; n++) { + float out = 0.7f * sinf(gPhase); + gPhase += 2.0 * M_PI * gFrequency * gInverseSampleRate; + if(gPhase > 2.0 * M_PI) + gPhase -= 2.0 * M_PI; + + for(int channel = 0; channel < gNumAudioChannels; channel++) + audioOut[n * gNumAudioChannels + channel] = out; + if(gCount==0){ + scheduleAuxiliaryTask(transmitReceiveDataTask); + } + gCount++; + } +} + +// cleanup_render() is called once at the end, after the audio has stopped. +// Release any resources that were allocated in initialise_render(). + +void cleanup_render() +{ +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/network/network_readme.txt Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,24 @@ +Three simple c scripts can be used to test the network, in conjunction with the basic_network project: +udp-client.c, udp-client-sweep.c,d udp-server.c +compile them with gcc -o udp-client udp-client.c and similar +They can be compiled and run from either the host or the bbb + +usage +./udp-client 192.168.7.2 9998 #sends individual messages to the bbb on port 9998 +#enter desired values for frequency (and phase). +123.0;0; + +The parser is currently very stupid, so the format of the message has to be:: +frequencyValue;phaseValue; +example: +700.0;0.1; + +./udp-client-sweep 192.168.7.2 9998 +sends messages every 1ms to control the frequency of the oscillator, thus generating a sine sweep + +./udp-server 9999 +#will print the info received from BeagleRT with the following format +printf("%8d;%.3f;%.3;",gCounter,gFrequency,gPhase); +example: +88201;700.000;0.123; +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/network/udp-client-sweep.c Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,59 @@ +/* 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> + +void error(const char *); +int main(int argc, char *argv[]) +{ + int sock, n; + unsigned int length; + struct sockaddr_in server, from; + struct hostent *hp; + char buffer[256]; + + if (argc != 3) { printf("Usage: server port\n"); + exit(1); + } + + server.sin_family = AF_INET; + hp = gethostbyname(argv[1]); + if (hp==0) error("Unknown host"); + + bcopy((char *)hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_port = htons(atoi(argv[2])); + length=sizeof(struct sockaddr_in); + while (1){ + sock= socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) error("socket"); + bzero(buffer,256); +// printf("Please enter the message: "); +// fgets(buffer,255,stdin); + double freq=50; + while(1){ + freq*=1.001; + if(freq>20000) freq=50; + sprintf(buffer,"%.4f;",freq); + n=sendto(sock,buffer, + strlen(buffer),0,(const struct sockaddr *)&server,length); + if (n < 0) error("Sendto"); + usleep(1000); + } + } + close(sock); + return 0; +} + +void error(const char *msg) +{ + perror(msg); + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/network/udp-client.c Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,52 @@ +/* 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> + +void error(const char *); +int main(int argc, char *argv[]) +{ + int sock, n; + unsigned int length; + struct sockaddr_in server, from; + struct hostent *hp; + char buffer[256]; + + if (argc != 3) { printf("Usage: server port\n"); + exit(1); + } + + server.sin_family = AF_INET; + hp = gethostbyname(argv[1]); + if (hp==0) error("Unknown host"); + + bcopy((char *)hp->h_addr, + (char *)&server.sin_addr, + hp->h_length); + server.sin_port = htons(atoi(argv[2])); + length=sizeof(struct sockaddr_in); + while (1){ + sock= socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) error("socket"); + bzero(buffer,256); + printf("Please enter the message: "); + fgets(buffer,255,stdin); + n=sendto(sock,buffer, + strlen(buffer),0,(const struct sockaddr *)&server,length); + if (n < 0) error("Sendto"); + } + close(sock); + return 0; +} + +void error(const char *msg) +{ + perror(msg); + exit(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/resources/network/udp-server.c Mon May 11 19:50:48 2015 +0100 @@ -0,0 +1,54 @@ +/* Creates a datagram server. The port + number is passed as an argument. This + server runs forever */ + +#include <sys/types.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <string.h> +#include <netdb.h> +#include <stdio.h> + +void error(const char *msg) +{ + perror(msg); + exit(0); +} + +int main(int argc, char *argv[]) +{ + int sock, length, n; + socklen_t fromlen; + struct sockaddr_in server; + struct sockaddr_in from; + char buf[1024]; + + if (argc < 2) { + fprintf(stderr, "ERROR, no port provided\n"); + exit(0); + } + + sock=socket(AF_INET, SOCK_DGRAM, 0); + if (sock < 0) error("Opening socket"); + length = sizeof(server); + bzero(&server,length); + server.sin_family=AF_INET; + server.sin_addr.s_addr=INADDR_ANY; + server.sin_port=htons(atoi(argv[1])); + if (bind(sock,(struct sockaddr *)&server,length)<0) + error("binding"); + fromlen = sizeof(struct sockaddr_in); + while (1) { + n = recvfrom(sock,buf,1024,0,(struct sockaddr *)&from,&fromlen); + if (n < 0) error("recvfrom"); + write(1,"Received a datagram: ",21); + write(1,buf,n); + n = sendto(sock,"Got your message\n",17, + 0,(struct sockaddr *)&from,fromlen); + if (n < 0) error("sendto"); + } + return 0; + } +