Working hard on ddcd.
This commit is contained in:
parent
4380bec6fa
commit
71e80ea809
3 changed files with 142 additions and 24 deletions
1
Makefile
1
Makefile
|
@ -67,6 +67,7 @@ install: all
|
|||
install -m 0755 libcsdr.so /usr/lib
|
||||
install -m 0755 csdr /usr/bin
|
||||
install -m 0755 csdr-fm /usr/bin
|
||||
install -m 0755 ddcd /usr/bin
|
||||
ldconfig
|
||||
uninstall:
|
||||
rm /usr/lib/libcsdr.so /usr/bin/csdr /usr/bin/csdr-fm
|
||||
|
|
142
ddcd.cpp
142
ddcd.cpp
|
@ -37,9 +37,16 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
int host_port = 0;
|
||||
char host_address[100] = "127.0.0.1";
|
||||
int decimation = 0;
|
||||
float transition_bw = 0.05;
|
||||
int bufsize = 1024;
|
||||
int bufsizeall;
|
||||
int pipe_max_size;
|
||||
char ddc_method_str[100] = "td";
|
||||
ddc_method_t ddc_method;
|
||||
pid_t main_dsp_proc;
|
||||
pid_t pgrp;
|
||||
int input_pipe = STDIN_FILENO; //can be stdin, or the stdout of main_subprocess
|
||||
|
||||
char* buf;
|
||||
|
||||
int set_nonblocking(int fd)
|
||||
|
@ -71,7 +78,9 @@ int main(int argc, char* argv[])
|
|||
{"port", required_argument, 0, 'p' },
|
||||
{"address", required_argument, 0, 'a' },
|
||||
{"decimation", required_argument, 0, 'd' },
|
||||
{"bufsize", required_argument, 0, 'b' }
|
||||
{"bufsize", required_argument, 0, 'b' },
|
||||
{"method", required_argument, 0, 'm' }
|
||||
{"transition", required_argument, 0, 't' }
|
||||
};
|
||||
c = getopt_long(argc, argv, "p:a:d:b:", long_options, &option_index);
|
||||
if(c==-1) break;
|
||||
|
@ -90,16 +99,37 @@ int main(int argc, char* argv[])
|
|||
case 'b':
|
||||
bufsize=atoi(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
host_address[100-1]=0;
|
||||
strncpy(ddc_method_str,optarg,100-1);
|
||||
break;
|
||||
case 't':
|
||||
sscanf(optarg,"%g",&transition_bw);
|
||||
break;
|
||||
case 0:
|
||||
case '?':
|
||||
case ':':
|
||||
default:
|
||||
printf(" 0%o ??\n", c);
|
||||
default:;
|
||||
}
|
||||
}
|
||||
|
||||
if(!decimation) error_exit(MSG_START "missing required command line argument, --decimation.\n");
|
||||
if(!host_port) error_exit(MSG_START "missing required command line argument, --port.\n");
|
||||
if(!decimation) print_exit(MSG_START "missing required command line argument, --decimation.\n");
|
||||
if(!host_port) print_exit(MSG_START "missing required command line argument, --port.\n");
|
||||
if(decimation<0) print_exit(MSG_START "invalid value for --decimation (should be >0).\n");
|
||||
if(decimation==1) fprintf(stderr, MSG_START "decimation = 1, just copying raw samples.\n");
|
||||
if(transition_bw<0||transition_bw>0.5) print_exit(MSG_START "invalid value for --transition (should be between 0 and 0.5).\n");
|
||||
|
||||
if(!strcmp(ddc_method_str,"td"))
|
||||
{
|
||||
ddc_method = M_TD;
|
||||
fprintf(stderr, MSG_START "method is M_TD (default).\n");
|
||||
}
|
||||
else if (!strcmp(ddc_method_str,"fastddc"))
|
||||
{
|
||||
ddc_method = M_FASTDDC;
|
||||
fprintf(stderr, MSG_START "method is M_FASTDDC.\n");
|
||||
}
|
||||
else print_exit(MSG_START "invalid parameter given to --method.\n");
|
||||
|
||||
struct sockaddr_in addr_host;
|
||||
int listen_socket;
|
||||
|
@ -109,7 +139,7 @@ int main(int argc, char* argv[])
|
|||
|
||||
int sockopt = 1;
|
||||
if( setsockopt(listen_socket, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt, sizeof(sockopt)) == -1 )
|
||||
error_exit(MSG_START "cannot set SO_REUSEADDR.\n"); //the best description on SO_REUSEADDR ever: http://stackoverflow.com/a/14388707/3182453
|
||||
error_exit(MSG_START "cannot set SO_REUSEADDR"); //the best description on SO_REUSEADDR ever: http://stackoverflow.com/a/14388707/3182453
|
||||
|
||||
memset(&addr_host,'0',sizeof(addr_host));
|
||||
addr_host.sin_family=AF_INET;
|
||||
|
@ -117,13 +147,13 @@ int main(int argc, char* argv[])
|
|||
addr_host.sin_addr.s_addr = INADDR_ANY;
|
||||
|
||||
if( (addr_host.sin_addr.s_addr=inet_addr(host_address)) == INADDR_NONE )
|
||||
error_exit(MSG_START "invalid host address.\n");
|
||||
error_exit(MSG_START "invalid host address");
|
||||
|
||||
if( bind(listen_socket, (struct sockaddr*) &addr_host, sizeof(addr_host)) < 0 )
|
||||
error_exit(MSG_START "cannot bind() address to the socket.\n");
|
||||
error_exit(MSG_START "cannot bind() address to the socket");
|
||||
|
||||
if( listen(listen_socket, 10) == -1 )
|
||||
error_exit(MSG_START "cannot listen() on socket.\n");
|
||||
error_exit(MSG_START "cannot listen() on socket");
|
||||
|
||||
fprintf(stderr,MSG_START "listening on %s:%d\n", inet_ntoa(addr_host.sin_addr), host_port);
|
||||
|
||||
|
@ -131,18 +161,9 @@ int main(int argc, char* argv[])
|
|||
socklen_t addr_cli_len = sizeof(addr_cli);
|
||||
int new_socket;
|
||||
|
||||
//Set stdin and listen_socket to non-blocking
|
||||
if(set_nonblocking(STDIN_FILENO) || set_nonblocking(listen_socket))
|
||||
error_exit(MSG_START "cannot set_nonblocking().\n");
|
||||
|
||||
bufsizeall = bufsize*sizeof(char);
|
||||
buf = (char*)malloc(bufsizeall);
|
||||
|
||||
FD_ZERO(&select_fds);
|
||||
FD_SET(listen_socket, &select_fds);
|
||||
FD_SET(STDIN_FILENO, &select_fds);
|
||||
int highfd = ((listen_socket>STDIN_FILENO)?listen_socket:STDIN_FILENO) + 1;
|
||||
|
||||
FILE* tempfile = fopen("/proc/sys/fs/pipe-max-size","r");
|
||||
if(!tempfile)
|
||||
{
|
||||
|
@ -159,6 +180,46 @@ int main(int argc, char* argv[])
|
|||
// perror("failed to fcntl(STDIN_FILENO, F_SETPIPE_SZ, ...)");
|
||||
}
|
||||
|
||||
//We'll see if it is a good idea:
|
||||
setpgrp();
|
||||
pgrp = getpgrp();
|
||||
|
||||
//Start DSP subprocess from the main process if required
|
||||
char main_subprocess_cmd_buf[500];
|
||||
pid_t main_subprocess_pid = 0;
|
||||
|
||||
int pipe_m2s_ctl[2]; //main to subprocess :: control channel
|
||||
int pipe_s2m[2]; //subprocess to main
|
||||
|
||||
if(pipe(pipe_m2s_ctl)) error_exit(MSG_START "couldn't create pipe_m2s_ctl");
|
||||
if(pipe(pipe_s2m)) error_exit(MSG_START "couldn't create pipe_s2m");
|
||||
|
||||
if(decimation!=1)
|
||||
{
|
||||
switch(ddc_method)
|
||||
{
|
||||
case M_TD:
|
||||
break;
|
||||
case M_FASTDDC:
|
||||
sprintf(main_subprocess_cmd_buf, subprocess_args_fastddc_1, decimation, tansition_bw);
|
||||
close(STDIN_FILENO); // redirect stdin to the stdin of the subprocess
|
||||
main_subprocess_pid = run_subprocess( main_subprocess_cmd_buf, 0, pipe_s2m );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int highfd = 0;
|
||||
FD_ZERO(&select_fds);
|
||||
FD_SET(listen_socket, &select_fds);
|
||||
maxfd(&highfd, listen_socket);
|
||||
if(main_subprocess_pid) input_pipe = pipe_s2m[1]; //else STDIN_FILENO
|
||||
FD_SET(input_pipe, &select_fds);
|
||||
maxfd(&highfd, input_pipe);
|
||||
|
||||
//Set stdin and listen_socket to non-blocking
|
||||
if(set_nonblocking(input_pipe) || set_nonblocking(listen_socket)) //don't do it before subprocess fork!
|
||||
error_exit(MSG_START "cannot set_nonblocking()");
|
||||
|
||||
for(;;)
|
||||
{
|
||||
//Let's wait until there is any new data to read, or any new connection!
|
||||
|
@ -173,17 +234,17 @@ int main(int argc, char* argv[])
|
|||
this_client->socket = new_socket;
|
||||
if(pipe(this_client->pipefd) == -1)
|
||||
{
|
||||
perror(MSG_START "cannot open new pipe() for the client.\n");
|
||||
perror(MSG_START "cannot open new pipe() for the client");
|
||||
continue;
|
||||
}
|
||||
if(fcntl(this_client->pipefd[1], F_SETPIPE_SZ, pipe_max_size) == -1)
|
||||
perror("failed to F_SETPIPE_SZ for the client pipe!");
|
||||
perror("failed to F_SETPIPE_SZ for the client pipe");
|
||||
if(this_client->pid = fork())
|
||||
{
|
||||
//We're the parent
|
||||
set_nonblocking(this_client->pipefd[1]);
|
||||
clients.push_back(this_client);
|
||||
printf("client pid: %d\n", this_client->pid);
|
||||
fprintf(stderr, MSG_START "client pid: %d\n", this_client->pid);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -193,7 +254,7 @@ int main(int argc, char* argv[])
|
|||
}
|
||||
}
|
||||
|
||||
int retval = read(STDIN_FILENO, buf, bufsizeall);
|
||||
int retval = read(input_pipe, buf, bufsizeall);
|
||||
if(retval==0)
|
||||
{
|
||||
//end of input stream, close clients and exit
|
||||
|
@ -239,6 +300,30 @@ int main(int argc, char* argv[])
|
|||
return 0;
|
||||
}
|
||||
|
||||
pid_t run_subprocess(char* cmd, int* pipe_in, int* pipe_out)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if(p < 0) return 0; //fork failed
|
||||
if(p==0)
|
||||
{
|
||||
//We're the subprocess
|
||||
if(fcntl(pipe_in[1], F_SETPIPE_SZ, pipe_max_size) == -1) perror("Failed to F_SETPIPE_SZ in run_subprocess()");
|
||||
if(pipe_in)
|
||||
{
|
||||
close(pipe_in[1]);
|
||||
dup2(pipe_in[0], STDIN_FILENO);
|
||||
}
|
||||
if(pipe_out)
|
||||
{
|
||||
close(pipe_out[0]);
|
||||
dup2(pipe_out[1], STDOUT_FILENO);
|
||||
}
|
||||
execl("/bin/bash","bash","-c",cmd, 0);
|
||||
error_exit(MSG_START "run_subprocess failed to execute command")
|
||||
}
|
||||
else return pid;
|
||||
}
|
||||
|
||||
void print_client(client_t* client, const char* what)
|
||||
{
|
||||
fprintf(stderr,MSG_START "(client %s:%d) %s\n", inet_ntoa(client->addr.sin_addr), client->addr.sin_port, what);
|
||||
|
@ -251,7 +336,7 @@ void client_cleanup()
|
|||
|
||||
void client()
|
||||
{
|
||||
fprintf(stderr, "I'm the client\n");
|
||||
print_client(this_client, "client process forked.");
|
||||
for(;;)
|
||||
{
|
||||
read(this_client->pipefd[0],buf,bufsizeall);
|
||||
|
@ -268,3 +353,14 @@ void error_exit(const char* why)
|
|||
perror(why);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void print_exit(const char* why)
|
||||
{
|
||||
fprintf(stderr, "%s", why);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void maxfd(int* maxfd, int fd)
|
||||
{
|
||||
if(fd>*maxfd) *maxfd=fd+1;
|
||||
}
|
||||
|
|
21
ddcd.h
21
ddcd.h
|
@ -23,10 +23,31 @@ typedef struct client_s
|
|||
pid_t pid;
|
||||
int pipefd[2];
|
||||
int error;
|
||||
pid_t dsp_proc;
|
||||
} client_t;
|
||||
|
||||
|
||||
void client();
|
||||
void error_exit(const char* why);
|
||||
void print_exit(const char* why);
|
||||
void print_client(client_t* client, const char* what);
|
||||
int proc_exists(pid_t pid);
|
||||
void run_subprocess(char* cmd, int* pipe_in, int* pipe_out);
|
||||
void maxfd(int* maxfd, int fd);
|
||||
|
||||
typedef enum ddc_method_e
|
||||
{
|
||||
M_TD,
|
||||
M_FASTDDC
|
||||
} ddc_method_t;
|
||||
|
||||
const char subprocess_cmd_td[] = "csdr "
|
||||
#ifdef NEON_OPTS
|
||||
"shift_addfast_cc"
|
||||
#else
|
||||
"shift_unroll_cc"
|
||||
#endif
|
||||
" --pipe %d,%d | csdr fir_decimate_cc %d %g" };
|
||||
|
||||
const char subprocess_args_fastddc_1[] = "csdr fastddc_fwd_cc %d %g";
|
||||
const char subprocess_args_fastddc_2[] = "csdr fastddc_inv_cc %d --pipe %d,%d %g";
|
||||
|
|
Loading…
Reference in a new issue