/* ***************************************************************************** * 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 . * * ***************************************************************************** * 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 #include #include #include #include #include #include #include // usleep() #include // ntohl() #include #include #include #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; output(ANSI_YELLOW" WAVEFORM Version 1.0.3, Console alive.\n"ANSI_WHITE); } 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; }