smartsdr-dsp/DSP_API/main.c

184 lines
5.2 KiB
C
Raw Normal View History

/* *****************************************************************************
* main.c 2014 SEP 01
*
* Author: Graham / KE9H
* Date created: August 5, 2014
*
* Wrapper program for "Embedded FreeDV" including CODEC2.
*
* Derived, in part from code provided by David Rowe under LGPL in:
* freedv_rx.c
* freedv_tx.c
*
* Calls and API defined by David Rowe in
* freedv_api.c
* freedv_api.h
*
* Portions of this file are Copyright (C) 2014 David Rowe
*
* *****************************************************************************
*
* Copyright (C) 2014 FlexRadio Systems.
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* *****************************************************************************
* TODO
* distinguish between rx data and tx data packets?
* discard rx data and tx data packet if wrong type?
* get call for S/N
*
*
*
**************************************************************************** */
#include <assert.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h> // usleep()
#include <netinet/in.h> // ntohl()
#include <signal.h>
#include <execinfo.h>
#include <ucontext.h>
#include "smartsdr_dsp_api.h"
#include "common.h"
const char* APP_NAME = "FreeDV"; // Name of Application
//const char* CFG_FILE = "FreeDV.cfg"; // Name of associated configuration file
char * cfg_path = NULL;
static sem_t shutdown_sem;
/* This structure mirrors the one found in /usr/include/asm/ucontext.h */
typedef struct _sig_ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
} sig_ucontext_t;
extern char *strsignal (int __sig);
void segfault_sigaction(int signal, siginfo_t *si, void *arg)
{
void * array[50];
char ** messages;
int size, i;
sig_ucontext_t * uc;
uc = (sig_ucontext_t *)arg;
fprintf(stderr, "\r\n\033[41;37m Caught signal %d (%s) at address 0x%08X\033[m\n", signal, strsignal(signal), (uint32)si->si_addr);
size = backtrace(array, 50);
messages = backtrace_symbols(array, size);
/* skip first stack frame (points here) */
for (i = 2; i < size && messages != NULL; ++i)
{
printf("%d-",i);
fprintf(stderr, "TRACE: (%d) %s @ ", i, messages[i]);
// Get's line number of fault
char syscom[256];
sprintf(syscom,"eu-addr2line -e %s %p","./freedv" , array[i]);
system(syscom);
}
free(messages);
exit(EXIT_FAILURE);
}
void setup_segfault_handler(void)
{
struct sigaction sa;
memset(&sa, 0, sizeof(struct sigaction));
sigemptyset(&sa.sa_mask);
sa.sa_sigaction = segfault_sigaction;
sa.sa_flags = SA_RESTART | SA_SIGINFO;
sigaction(SIGSEGV, &sa, NULL);
// ignore broken pipes
signal(SIGPIPE, SIG_IGN);
}
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// main()
int main( int argc, char * argv[])
{
const char * console_param = "--console";
const char * restrict_ip_param = "--ip=";
const char * config_path_param = "--cfg_path=";
BOOL enable_console = FALSE;
char * restrict_ip = NULL;
/* Semaphore will be used to signal end of execution */
sem_init(&shutdown_sem, 0, 0);
/* If compiled in DEBUG then seg-faults will include a stack trace */
setup_segfault_handler();
int i = 0;
for ( i = 1 ; i < argc; i++ ) {
if (strncmp(argv[i], console_param, strlen(console_param)) == 0 ) {
/* We will run with a console for input.
* This is normally disabled so that the waveform can run as a
* service or as a subprocess.
*/
enable_console = TRUE;
} else if ( strncmp(argv[i], restrict_ip_param, strlen(restrict_ip_param)) == 0 ) {
restrict_ip = safe_malloc(strlen(argv[i]));
strncpy(restrict_ip, argv[i]+strlen(restrict_ip_param), strlen(argv[i]));
output("Restrict IP = '%s'\n", restrict_ip);
} else if ( strncmp(argv[i], config_path_param ,strlen(config_path_param)) == 0 ) {
cfg_path = safe_malloc(strlen(argv[i]));
strncpy(cfg_path, argv[i] + strlen(config_path_param), strlen(argv[i]));
output("Config Path = '%s'\n", cfg_path);
} else {
output("Unknown console parameter - '%s'\n", argv[i]);
}
}
if ( ! cfg_path ) {
cfg_path = safe_malloc(strlen("./") + 1);
strncpy(cfg_path, "./", strlen("./") + 1);
}
SmartSDR_API_Init(enable_console, restrict_ip);
if ( restrict_ip ) {
safe_free(restrict_ip);
}
/* Wait to be notified of shutdown */
sem_wait(&shutdown_sem);
safe_free(cfg_path);
return 0;
}