diff options
author | Andreas Eversberg <jolly@eversberg.eu> | 2020-09-27 14:17:11 +0200 |
---|---|---|
committer | Andreas Eversberg <jolly@eversberg.eu> | 2020-12-29 19:02:56 +0100 |
commit | fde7cc2ce319bf294ded54da0822672fe33b1923 (patch) | |
tree | b3c87039dbc99fa5dc2f67a11a91ae8196e7ab4c /src/router/main.c |
Initial GIT import
Diffstat (limited to 'src/router/main.c')
-rw-r--r-- | src/router/main.c | 260 |
1 files changed, 260 insertions, 0 deletions
diff --git a/src/router/main.c b/src/router/main.c new file mode 100644 index 0000000..b3a404e --- /dev/null +++ b/src/router/main.c @@ -0,0 +1,260 @@ +/* osmo-cc-router main + * + * (C) 2020 by Andreas Eversberg <jolly@eversberg.eu> + * All Rights Reserved + * + * 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/>. + */ + +#include <stdio.h> +#include <unistd.h> +#include <errno.h> +#include <signal.h> +#include <string.h> +#include <stdint.h> +#include <stdlib.h> +#include <termios.h> +#include "../libdebug/debug.h" +#include "../liboptions/options.h" +#include "../libg711/g711.h" +#include "call.h" +#include "audio.h" +#include "display.h" + +int num_kanal = 1; +osmo_cc_endpoint_t *cc_ep = NULL; + +static char *routing_script = "~/.osmocom/router/routing.sh"; +static char *routing_shell = "bash"; +#define MAX_CC_ARGS 1024 +static int cc_argc = 0; +static const char *cc_argv[MAX_CC_ARGS]; + +static void print_usage(const char *app) +{ + printf("Usage: %s [<options>]\n", app); +} + +static void print_help() +{ + /* - - */ + printf(" -h --help\n"); + printf(" This help\n"); + printf(" -v --verbose <level> | <level>,<category>[,<category>[,...]] | list\n"); + printf(" Use 'list' to get a list of all levels and categories\n"); + printf(" Verbose level: digit of debug level (default = '%d')\n", debuglevel); + printf(" Verbose level+category: level digit followed by one or more categories\n"); + printf(" -r --routing-script <script>\n"); + printf(" Define the script/executable that is executed to perform routing\n"); + printf(" decision for each call. (default = %s)\n", routing_script); + printf(" -s --routing-shell <>\n"); + printf(" Define the shell to run the routing scrip. (default = %s)\n", routing_shell); + printf(" -C --cc \"<osmo-cc arg>\" [--cc ...]\n"); + printf(" Pass arguments to Osmo-CC endpoint. Use '-cc help' for description.\n"); +} + +#define OPT_XXX 256 + +static void add_options(void) +{ + option_add('h', "help", 0); + option_add('v', "verbose", 1); + option_add('r', "routing-script", 1); + option_add('s', "routing-shell", 1); + option_add('C', "cc", 1); +} + +static int handle_options(int short_option, int argi, char **argv) +{ + int rc; + + switch (short_option) { + case 'h': + print_usage(argv[0]); + print_help(); + return 0; + case 'v': + if (!strcasecmp(argv[argi], "list")) { + debug_list_cat(); + return 0; + } + rc = parse_debug_opt(argv[argi]); + if (rc < 0) { + fprintf(stderr, "Failed to parse debug option, please use -h for help.\n"); + return rc; + } + break; + case 'r': + routing_script = strdup(argv[argi]); + break; + case 's': + routing_shell = strdup(argv[argi]); + break; + case 'C': + if (!strcasecmp(argv[argi], "help")) { + osmo_cc_help(); + return 0; + } + if (cc_argc == MAX_CC_ARGS) { + fprintf(stderr, "Too many osmo-cc args!\n"); + break; + } + cc_argv[cc_argc++] = strdup(argv[argi]); + break; + default: + return -EINVAL; + } + return 1; +} + +static int quit = 0; +void sighandler(int sigset) +{ + if (sigset == SIGHUP || sigset == SIGPIPE) + return; + + fprintf(stderr, "\nSignal %d received.\n", sigset); + + quit = 1; +} + +static int get_char() +{ + struct timeval tv = {0, 0}; + fd_set fds; + char c = 0; + int __attribute__((__unused__)) rc; + + FD_ZERO(&fds); + FD_SET(0, &fds); + select(0+1, &fds, NULL, NULL, &tv); + if (FD_ISSET(0, &fds)) { + rc = read(0, &c, 1); + return c; + } else + return -1; +} + +int main(int argc, char *argv[]) +{ + double last_time_call = 0, now; + int argi, rc; + struct termios term, term_orig; + int c; + + /* init FM */ + fm_init(0); + + /* init codecs (for recording) */ + g711_init(); + + /* handle options / config file */ + add_options(); + rc = options_config_file("~/.osmocom/router/router.conf", handle_options); + if (rc < 0) + return 0; + argi = options_command_line(argc, argv, handle_options); + if (argi <= 0) + return argi; + + /* init osmo-cc endpoint */ + cc_ep = calloc(1, sizeof(*cc_ep)); + if (!cc_ep) + goto error; + rc = osmo_cc_new(cc_ep, OSMO_CC_VERSION, NULL, OSMO_CC_LOCATION_PRIV_SERV_LOC_USER, cc_message, NULL, NULL, cc_argc, cc_argv); + if (rc < 0) + goto error; + + /* init call handling */ + call_init(cc_ep, routing_script, routing_shell); + + /* prepare terminal */ + tcgetattr(0, &term_orig); + term = term_orig; + term.c_lflag &= ~(ISIG|ICANON|ECHO); + term.c_cc[VMIN]=1; + term.c_cc[VTIME]=2; + tcsetattr(0, TCSANOW, &term); + + /* catch signals */ + signal(SIGINT, sighandler); + signal(SIGHUP, sighandler); + signal(SIGTERM, sighandler); + signal(SIGPIPE, sighandler); + + printf("\nRouter is ready to process calls.\n\n"); + + while (!quit) { + int w; + + /* send clock calls to play/record audio files */ + now = get_time(); + if (now - last_time_call >= 0.1) + last_time_call = now; + if (now - last_time_call >= 0.020) { + last_time_call += 0.020; + /* call clock every 20ms */ + call_clock(160); + } + + process_timer(); + call_media_handle(); + do { + w = 0; + w |= osmo_cc_handle(); + w |= call_handle(); + } while (w); + usleep(1000); + + /* process keyboard input */ +next_char: + c = get_char(); + switch (c) { + case 3: + printf("CTRL+c received, quitting!\n"); + quit = 1; + goto next_char; + case 'c': + display_status_on(-1); + goto next_char; + } + } + + /* reset signals */ + signal(SIGINT, SIG_DFL); + signal(SIGTSTP, SIG_DFL); + signal(SIGHUP, SIG_DFL); + signal(SIGTERM, SIG_DFL); + signal(SIGPIPE, SIG_DFL); + + /* reset terminal */ + tcsetattr(0, TCSANOW, &term_orig); + + +error: + if (cc_ep) { + /* exit call handling */ + call_exit(); + + /* exit osmo-cc endpoint */ + osmo_cc_delete(cc_ep); + free(cc_ep); + } + + /* exit FM */ + fm_exit(); + + return 0; +} + |