buf+j, 4 );
}
if( *payl->outfile > 0 ) {
k=write( *payl->outfile, buf, 200 );
if( k==-1 ) {
fprintf( stderr, "Error writing audio stream error %d - %s\n", errno, strerror(errno) );
}
}
}
return NULL;
}
void *FFTSend( void *pay ) {
double *co = NULL;
double *si = NULL;
double *fftr = NULL;
double *ffti = NULL;
double *coeff = NULL;
unsigned char *fftout = NULL;
int N;
double co1, si1;
double pi=3.141592653589793238462643383279502884197169399375105820974944592;
double fftdr, fftdi;
int j, k;
int m, p, md, ng, ig, i, ind, i1, i2, jd, kp;
long val;
char buf[1050];
int n;
int flipflop=0;
long freq;
payloadp payl=(payloadp)pay;
p=10;
N=1<con_b, payl->mut_b);
} else if( flipflop==1 ) {
pthread_cond_wait(payl->con_a, payl->mut_a);
} else {
pthread_cond_wait(payl->con_c, payl->mut_c);
}
// Time measurement
gettimeofday( &(payl->start), NULL );
// Read input data
if( flipflop==0 ) {
for( j=0, k=0; kbuftemp)[j]*coeff[k];
ffti[k]=((float *)payl->buftemp)[j+1]*coeff[k];
}
} else if( flipflop==1 ) {
for( j=0, k=0; kbuf)[j]*coeff[k];
ffti[k]=((float *)payl->buf)[j+1]*coeff[k];
}
} else {
for( j=0, k=0; kbufmed)[j]*coeff[k];
ffti[k]=((float *)payl->bufmed)[j+1]*coeff[k];
}
}
m = N/2;
p = 10;
// FFT Compute
for( j=0,ng=1,md=m; j>= 1;
ng <<= 1;
}
// Coefficients reordering
for( j=0; j>= 1;
kp >>= 1;
}
if( k>j ) {
fftdr = fftr[j];
fftdi = ffti[j];
fftr[j] = fftr[k];
ffti[j] = ffti[k];
fftr[k] = fftdr;
ffti[k] = fftdi;
}
}
// Absolute value
for( j=0; j 50 ) {
val=50;
}
fftout[j]=200+(char)val;
// fprintf( stderr, "%04d ", fftout[j] );
}
// time measurement
gettimeofday( &(payl->stop), NULL );
// fprintf( stderr, "FFT time= %f mSec\n", (payl->stop.tv_sec-payl->start.tv_sec)*1000+0.001*(payl->stop.tv_usec-payl->start.tv_usec) );
// FFT write out
if( *payl->outfile >0 ) {
buf[0]=0x82;
buf[1]=0x7e;
if( flipflop==0 ) {
buf[2]=0x02;
buf[3]=0x10;
buf[4]=0x01; //fft type
buf[5]='B';
buf[6]='F';
buf[7]=0x01;
memcpy( buf+8, (char *)payl->tune, 4 );
memcpy( buf+12, (char *)payl->att_lowpass_rate, 2 );
freq = htonl( *payl->freq );
memcpy( buf+14, &freq, 4 );
memcpy( buf+20, fftout+512+256, 256 );
memcpy( buf+20+256, fftout, 256 );
n=write( *payl->outfile, buf, 512+20 );
} else if( flipflop==1 ) {
buf[2]=0x03;
buf[3]=0x90;
buf[4]=0x02; //fft type
buf[5]='H';
buf[6]='F';
buf[7]=0x01;
memcpy( buf+8, (char *)payl->tune, 4 );
memcpy( buf+12, (char *)payl->att_lowpass_rate, 2 );
freq = htonl( *payl->freq );
memcpy( buf+14, &freq, 4 );
memcpy( buf+20, fftout+512+64, 512-64 );
memcpy( buf+512+20-64, fftout, 512-64 );
n=write( *payl->outfile, buf, 1024+20-128 );
} else {
buf[2]=0x03;
buf[3]=0x90;
buf[4]=0x03; //fft type
buf[5]='M';
buf[6]='F';
buf[7]=0x01;
memcpy( buf+8, (char *)payl->tune, 4 );
memcpy( buf+12, (char *)payl->att_lowpass_rate, 2 );
freq = htonl( *payl->freq );
memcpy( buf+14, &freq, 4 );
memcpy( buf+20, fftout+512+64, 512-64 );
memcpy( buf+512+20-64, fftout, 512-64 );
n=write( *payl->outfile, buf, 1024+20-128 );
}
if( n<0 ) {
fprintf( stderr, "sent %d bytes %d %s\n", n, errno, strerror(errno) );fflush( stderr );
}
}
usleep( 30000 );
// fprintf( stderr, "post Round\n" );fflush( stderr );
}
return NULL;
}
static char *requestHeader[] = {
"GET ",
"Host: ",
"Sec-WebSocket-Version: ",
"Sec-WebSocket-Protocol: ",
"Sec-WebSocket-Key: ",
"Connection: keep-alive, Upgrade",
"Upgrade: websocket"
};
static char *keyHeader="Sec-WebSocket-Key: ";
void *tcpManage( void *payload ) {
int chfd;
FILE *bchfd;
char buf[1024];
char *hp, *pp;
struct sockaddr_in cliaddr;
int j, n, k;
payloadp payl = (payloadp)payload;
int status;
char keys[100];
int isFirst;
int pid;
pid = getpid();
chfd = *payl->outfile;
fprintf( stderr, "Receiving websocket on %d\n", chfd );
bchfd=fdopen( chfd, "r+" );
if( !bchfd ) {
fprintf( stderr, "Reopen-ing Error\n" );
exit( 12 );
}
hp = inet_ntoa(cliaddr.sin_addr);
if( !hp ) {
fprintf( stderr, "inet_ntoa Error\n" );
exit( 14 );
} else {
fprintf( stderr, "Connected by %s\n", hp );
}
for( status=0;; ) {
fprintf( stderr, "%d TCP loop\n", pid );
memset( buf, 0, sizeof( buf ) );
pp = fgets( buf, sizeof(buf), bchfd );
if( !pp && errno ) {
fprintf( stderr, "%d TCP read Error\n", pid );
exit( 15 );
}
if( !pp ) {
fprintf( stderr, "%d TCP read 0 bytes \n", pid );
continue;
}
if( buf[strlen(buf)-1]=='\n' ) {
fprintf( stderr, "%d Received %d bytes %s", pid, (int)strlen( buf ), buf );
for( j=0; j= XtNumber(requestHeader)+1 ) {
break;
}
}
n=fprintf( bchfd, "HTTP/1.1 101 Switching Protocols\r\n" );
fprintf( stderr, "sent %d bytes error %d\n", n, errno );
fprintf( stderr, "HTTP/1.1 101 Switching Protocols\r\n" );
n=fprintf( bchfd, "Upgrade: websocket\r\n" );
fprintf( stderr, "sent %d bytes error %d\n", n, errno );
fprintf( stderr, "Upgrade: websocket\r\n" );
n=fprintf( bchfd, "Connection: Upgrade\r\n" );
fprintf( stderr, "sent %d bytes error %d\n", n, errno );
fprintf( stderr, "Connection: Upgrade\r\n" );
// strcpy( keys, (const char *)"dGhlIHNhbXBsZSBub25jZQ==" );
sprintf( buf, "%s%s", keys, "258EAFA5-E914-47DA-95CA-C5AB0DC85B11" );
memset( keys, 0, sizeof( keys ) );
SHA1( (unsigned const char *)buf, strlen(buf), (unsigned char *)keys );
pp=g_base64_encode( (const guchar *)keys, strlen(keys) );
memset( keys, 0, sizeof( keys ) );
strcpy( keys, (const char *)pp );
g_free( pp );
n=fprintf( bchfd, "Sec-WebSocket-Accept: %s\r\n", keys );
fprintf( stderr, "Sec-WebSocket-Accept: %s\r\n", keys );
n=fprintf( bchfd, "Sec-WebSocket-Protocol: chat\r\n\r\n" );
fprintf( stderr, "Sec-WebSocket-Protocol: chat\r\n\r\n" );
fprintf( stderr, "sent %d bytes error %d\n", n, errno );
fflush( bchfd );
for( isFirst=1;; ) {
fprintf( stderr, "%d TCP rec cmd loop\n", pid );
fflush( stderr );
memset( buf, 0, sizeof( buf ) );
n = read( chfd, buf, sizeof(buf) );
if( n==-1 ) {
fprintf( stderr, "%d TCP read Error %d - %s on %d\n", pid, errno, strerror(errno), chfd );
exit( 15 );
}
if( !n ) {
fprintf( stderr, "%d TCP read 0 bytes \n", pid );
continue;
}
fprintf( stderr, "%d Received %d bytes : ", pid, n);
for( j=0; jpassphrase ) ) {
fprintf( stderr, "required >%s< differ from >%s<\n", payl->passphrase, buf+6 );
break;
}
} else {
strcpy( payl->buf, buf+6 );
fprintf( stderr, "%s\n", buf+6 );
for( j=0,pp=payl->buf,n=strlen(payl->buf); j<=n; j++ ) {
if( payl->buf[j]=='\n' ) {
payl->buf[j]=0;
}
if( payl->buf[j]==0 ) {
if( !strncmp( pp, "MODE=", 5 ) ) {
if( !strncmp( pp+5, "USB", 3 ) ) {
*payl->mod=0;
*payl->bfo=1850;
} else if( !strncmp( pp+5, "LSB", 3 ) ) {
*payl->mod=1;
*payl->bfo=-1850;
} else if( !strncmp( pp+5, "CW", 2 ) ) {
*payl->mod=2;
*payl->bfo=700;
} else {
*payl->mod=-1;
*payl->bfo=0;
}
fprintf( stderr, "MODE=%d\n", *payl->mod );
}
if( !strncmp( pp, "BW=", 3 ) ) {
if( !strncmp( pp+3, "NARROW", 6 ) ) {
*payl->bw=0;
} else if( !strncmp( pp+3, "MEDIUM", 6 ) ) {
*payl->bw=1;
} else if( !strncmp( pp+3, "WIDE", 4 ) ) {
*payl->bw=2;
} else {
*payl->bw=-1;
}
fprintf( stderr, "BW=%d\n", *payl->bw );
}
if( !strncmp( pp, "FC=", 3 ) ) {
sscanf( pp+3, "%d", payl->freq );
fprintf( stderr, "FC=%d\n", *payl->freq );
}
pp=payl->buf+j+1;
}
}
}
} else {
fprintf( stderr, "wrong message length: is %d instead of %d\n", j, n-6 );
break;
}
} else {
fprintf( stderr, "wrong message type: %x\n", buf[0] );
break;
}
}
return( NULL );
}
int main( int ac, char *av[], char **ev ) {
int res;
int port;
int outfile=0;
static int freq=0;
static int mod;
static int bw;
char *passphrase;
long tune;
long bfo;
short att_lowpass_rate;
int pfd;
struct sockaddr_in saddr;
struct sockaddr_in cliaddr;
unsigned int clilun;
int pid;
payload payl0;
pthread_t pthread0;
pthread_attr_t attr0;
struct sched_param prio0;
payload payl1;
pthread_t pthread1;
pthread_attr_t attr1;
struct sched_param prio1;
payload payl2;
pthread_t pthread2;
pthread_attr_t attr2;
struct sched_param prio2;
payload payl3;
pthread_t pthread3;
pthread_attr_t attr3;
struct sched_param prio3;
key_t shm_key;
int shm_id;
char* shmaddr1;
char* shmaddr2;
char* shm_cond1;
char* shm_cond2;
pthread_cond_t con_a = PTHREAD_COND_INITIALIZER;
pthread_cond_t con_b = PTHREAD_COND_INITIALIZER;
pthread_cond_t con_c = PTHREAD_COND_INITIALIZER;
pthread_mutex_t mut_a = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_b = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_c = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_ta = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mut_tb = PTHREAD_MUTEX_INITIALIZER;
static char buf_a[BUFFERSIZE];
static char buf_b[BUFFERSIZE];
static char buf_t[BUFFERSIZE*2];
static char buf_m[BUFFERSIZE*2];
static int lung_t;
fprintf( stderr, "Operations init elad-server version 1.0\n" );
// Read portnumber from Argument, if not 7777
if( ac<2 ) {
port = 7777;
} else {
port = atoi( av[1] );
}
fprintf( stderr, "portnumber: %d\n", port );
// Read shared memory from Argument, if not 6166530
if( ac<3 ) {
shm_key = 6166530;
} else {
shm_key = atol( av[2] );
}
if( ac<4 ) {
passphrase="accattatevillo";
} else {
passphrase = av[3];
}
// socket: create the socket
pfd = socket( AF_INET, SOCK_STREAM, 0 );
if( pfd == -1 ) {
fprintf( stderr, "Socket open error\n" );
exit( 7 );
}
int opt = 1;
setsockopt( pfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt , sizeof(int) );
memset( &saddr, 0, sizeof(saddr) );
saddr.sin_family = AF_INET;
saddr.sin_addr.s_addr = htonl( INADDR_ANY );
saddr.sin_port = htons( port );
if( bind( pfd, (struct sockaddr *) &saddr, sizeof( saddr ) ) == -1 ) {
fprintf( stderr, "Binding Error\n" );
exit( 8 );
}
if( listen( pfd, 1 ) == -1 ) {
fprintf( stderr, "Listening Error\n" );
exit( 10 );
}
fprintf( stderr, "Listening on port %d\n", port );
clilun = sizeof( cliaddr );
for( ;; ) {
// wait for a connection request
fprintf( stderr, "accepting\n" );
outfile = accept( pfd, (struct sockaddr *) &cliaddr, &clilun );
if( outfile == -1 ) {
fprintf( stderr, "Accept-ing Error\n" );
exit( 11 );
}
pid = fork( );
if( pid == -1 ) {
fprintf( stderr, "Accept-ing Error\n" );
exit( 11 );
}
if( pid > 0 ) {
fprintf( stderr, "%d child - operate on %d\n", pid, outfile );
break;
}
fprintf( stderr, "Father - continue\n" );
}
// create thread that manages websocket creation
memset( &payl0, 0, sizeof( payl1 ) );
payl0.outfile=&outfile;
payl0.buf=buf_t;
payl0.freq=&freq;
payl0.mod=&mod;
payl0.bw=&bw;
payl0.passphrase=passphrase;
payl0.tune=&tune;
payl0.bfo=&bfo;
payl0.att_lowpass_rate=&att_lowpass_rate;
prio0.sched_priority=50;
res=pthread_attr_init( &attr0 );
if( res ) { fprintf( stderr, "pthread_attr_init attr0 failed\n" ); }
res=pthread_create( &pthread0, &attr0, tcpManage, (void *)&payl0 );
if( res ) { fprintf( stderr, "pthread_create pthread 0 failed\n" ); }
res=pthread_setschedparam( pthread0, SCHED_RR, &prio0 );
if( res ) { fprintf( stderr, "pthread_setschedparam pthread 0 failed\n" ); }
fprintf( stderr, "websocket Processing thread a created\n" );
// Allocate and attach a shared memory segment
shm_id = shmget ( shm_key, (BUFFERSIZE+sizeof( pthread_cond_t )+6)*2, IPC_CREAT | S_IRUSR | S_IWUSR | 0666 );
if( shm_id==-1 ) {
fprintf( stderr, "erro allocating shmem %d %s\n", errno, strerror(errno) );fflush( stderr );
}
shm_cond1 = (char*) shmat (shm_id, 0, 0);
shmaddr1 = shm_cond1 + sizeof( pthread_cond_t );
shm_cond2 = shmaddr1 + BUFFERSIZE + 6;
shmaddr2 = shm_cond2 + sizeof( pthread_cond_t );
fprintf( stderr, "Shared %x memory attached at address %p\n", shm_id, shm_cond1 );
memset( &payl3, 0, sizeof( payl3 ) );
// create thread that receives and manages the data from shared memory
memset( &payl1, 0, sizeof( payl1 ) );
payl1.con=(pthread_cond_t *)shm_cond1;
payl1.mut=&mut_ta;
payl1.con_a=&con_a;
payl1.con_b=&con_b;
payl1.con_c=&con_c;
payl1.payload=(void *)&payl3;
payl1.buf=buf_a;
payl1.buftemp=buf_t;
payl1.bufmed=buf_m;
payl1.outfile=&outfile;
payl1.lung=&lung_t;
payl1.shmaddr=shmaddr1+6;
payl1.freq=&freq;
payl1.mod=&mod;
payl1.bw=&bw;
payl1.tune=&tune;
payl1.bfo=&bfo;
payl1.att_lowpass_rate=&att_lowpass_rate;
prio1.sched_priority=50;
res=pthread_attr_init( &attr1 );
if( res ) { fprintf( stderr, "pthread_attr_init attr1 failed\n" ); }
res=pthread_create( &pthread1, &attr1, hfThread, (void *)&payl1 );
if( res ) { fprintf( stderr, "pthread_create pthread 1 failed\n" ); }
res=pthread_setschedparam( pthread1, SCHED_RR, &prio1 );
if( res ) { fprintf( stderr, "pthread_setschedparam pthread 1 failed\n" ); }
fprintf( stderr, "HF Processing thread a created\n" );
// create thread that sends data to the websocket
memset( &payl2, 0, sizeof( payl2 ) );
payl2.con=(pthread_cond_t *)shm_cond2;
payl2.mut=&mut_tb;
payl2.con_a=&con_a;
payl2.con_b=&con_b;
payl2.con_c=&con_c;
payl2.buf=buf_b;
payl2.buftemp=buf_t;
payl2.bufmed=buf_m;
payl2.outfile=&outfile;
payl2.lung=&lung_t;
payl2.shmaddr=shmaddr2+6;
payl2.freq=&freq;
payl2.mod=&mod;
payl2.bw=&bw;
payl2.tune=&tune;
payl2.bfo=&bfo;
payl2.att_lowpass_rate=&att_lowpass_rate;
prio2.sched_priority=40;
res=pthread_attr_init( &attr2 );
if( res ) { fprintf( stderr, "pthread_attr_init attr2 failed\n" ); }
res=pthread_create( &pthread2, &attr2, hfThread, (void *)&payl2 );
if( res ) { fprintf( stderr, "pthread_create pthread 2 failed\n" ); }
res=pthread_setschedparam( pthread2, SCHED_RR, &prio2 );
if( res ) { fprintf( stderr, "pthread_setschedparam pthread 2 failed\n" ); }
fprintf( stderr, "HF Processing thread b created\n" );
// create thread that sends FFT to the websocket
payl3.con_a=&con_a;
payl3.mut_a=&mut_a;
payl3.con_b=&con_b;
payl3.mut_b=&mut_b;
payl3.con_c=&con_c;
payl3.mut_c=&mut_c;
payl3.buftemp=buf_t;
payl3.bufmed=buf_m;
payl3.buf=shmaddr1+6;
payl3.outfile=&outfile;
payl3.freq=&freq;
payl3.mod=&mod;
payl3.bw=&bw;
payl3.tune=&tune;
payl3.att_lowpass_rate=&att_lowpass_rate;
prio3.sched_priority=80;
res=pthread_attr_init( &attr3 );
if( res ) { fprintf( stderr, "pthread_attr_init attr3 failed\n" ); }
res=pthread_create( &pthread3, &attr3, FFTSend, (void *)&payl3 );
if( res ) { fprintf( stderr, "pthread_create pthread 3 failed\n" ); }
res=pthread_setschedparam( pthread3, SCHED_RR, &prio3 );
if( res ) { fprintf( stderr, "pthread_setschedparam pthread 3 failed\n" ); }
fprintf( stderr, "Send FFT thread created\n" );
// main loop
for( ;; ) {
sleep( 10 );
}
// dirty exit
fprintf( stderr, "Operations end\n" );
return 0;
}