--- asterisk-1.6.0-externalIvr-commands/apps/app_externalivr.c 2008-01-23 13:18:50.000000000 -0600 +++ asterisk-1.6.0-externalIvr-tcp-sockets/apps/app_externalivr.c 2008-01-23 15:08:07.000000000 -0600 @@ -35,7 +35,13 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 89512 $") +#include +#include +#include +#include +#include #include +#include #include "asterisk/lock.h" #include "asterisk/file.h" @@ -89,6 +95,8 @@ int eivr_events_fd, int eivr_commands_fd, int eivr_errors_fd, const char *args); +int eivr_connect_socket(struct ast_channel *chan, const char *host, int port); + static void send_eivr_event(FILE *handle, const char event, const char *data, const struct ast_channel *chan) { @@ -310,6 +318,12 @@ int gen_active = 0; int pid; char *buf, *pipe_delim_argbuf, *pdargbuf_ptr; + + char hostname[1024]; + char *port_str = NULL; + int port = 0; + int socket; + struct ivr_localuser foo = { .playlist = AST_LIST_HEAD_INIT_VALUE, .finishlist = AST_LIST_HEAD_INIT_VALUE, @@ -340,69 +354,96 @@ pdargbuf_ptr[0] = '|'; + if(!strncmp(args.cmd[0], "ivr://", 6)) { + /*communicate through socket to server*/ + if (chan->_state != AST_STATE_UP) { + ast_answer(chan); + } + if (ast_activate_generator(chan, &gen, u) < 0) { + ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n"); + goto exit; + } else + gen_active = 1; + + ast_chan_log(LOG_DEBUG, chan, "Parsing hostname:port for socket connect from \"%s\"\n", args.cmd[0]); + strncpy(hostname, args.cmd[0] + 6, sizeof(hostname)); + if((port_str = strchr(hostname, ':')) != NULL) { + port_str[0] = 0; + port_str += 1; + port = atoi(port_str); + } + if(!port) + port = 2949; /*default port, if one is not provided*/ - if (pipe(child_stdin)) { - ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno)); - goto exit; - } + if((socket = eivr_connect_socket(chan,hostname, port)) < 0) { + ast_chan_log(LOG_WARNING, chan, "Failed to connect socket to %s:%d\n", hostname, port); + goto exit; + } else + res = eivr_comm(chan, u, socket, socket, 0, pipe_delim_argbuf); + } else { + if (pipe(child_stdin)) { + ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child input: %s\n", strerror(errno)); + goto exit; + } - if (pipe(child_stdout)) { - ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child output: %s\n", strerror(errno)); - goto exit; - } + if (pipe(child_stdout)) { + ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child output: %s\n", strerror(errno)); + goto exit; + } - if (pipe(child_stderr)) { - ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child errors: %s\n", strerror(errno)); - goto exit; - } + if (pipe(child_stderr)) { + ast_chan_log(LOG_WARNING, chan, "Could not create pipe for child errors: %s\n", strerror(errno)); + goto exit; + } - if (chan->_state != AST_STATE_UP) { - ast_answer(chan); - } + if (chan->_state != AST_STATE_UP) { + ast_answer(chan); + } - if (ast_activate_generator(chan, &gen, u) < 0) { - ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n"); - goto exit; - } else - gen_active = 1; + if (ast_activate_generator(chan, &gen, u) < 0) { + ast_chan_log(LOG_WARNING, chan, "Failed to activate generator\n"); + goto exit; + } else + gen_active = 1; - pid = fork(); - if (pid < 0) { - ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); - goto exit; - } + pid = fork(); + if (pid < 0) { + ast_log(LOG_WARNING, "Failed to fork(): %s\n", strerror(errno)); + goto exit; + } - if (!pid) { - /* child process */ - int i; - - signal(SIGPIPE, SIG_DFL); - pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); - - if (ast_opt_high_priority) - ast_set_priority(0); - - dup2(child_stdin[0], STDIN_FILENO); - dup2(child_stdout[1], STDOUT_FILENO); - dup2(child_stderr[1], STDERR_FILENO); - for (i = STDERR_FILENO + 1; i < 1024; i++) - close(i); - execv(args.cmd[0], args.cmd); - fprintf(stderr, "Failed to execute '%s': %s\n", args.cmd[0], strerror(errno)); - _exit(1); - } else { - /* parent process */ + if (!pid) { + /* child process */ + int i; + + signal(SIGPIPE, SIG_DFL); + pthread_sigmask(SIG_UNBLOCK, &fullset, NULL); + + if (ast_opt_high_priority) + ast_set_priority(0); + + dup2(child_stdin[0], STDIN_FILENO); + dup2(child_stdout[1], STDOUT_FILENO); + dup2(child_stderr[1], STDERR_FILENO); + for (i = STDERR_FILENO + 1; i < 1024; i++) + close(i); + execv(args.cmd[0], args.cmd); + fprintf(stderr, "Failed to execute '%s': %s\n", args.cmd[0], strerror(errno)); + _exit(1); + } else { + /* parent process */ - close(child_stdin[0]); - child_stdin[0] = 0; - close(child_stdout[1]); - child_stdout[1] = 0; - close(child_stderr[1]); - child_stderr[1] = 0; - res = eivr_comm(chan, u, child_stdin[1], child_stdout[0], child_stderr[0], pipe_delim_argbuf); + close(child_stdin[0]); + child_stdin[0] = 0; + close(child_stdout[1]); + child_stdout[1] = 0; + close(child_stderr[1]); + child_stderr[1] = 0; + res = eivr_comm(chan, u, child_stdin[1], child_stdout[0], child_stderr[0], pipe_delim_argbuf); - } + } + } exit: if (gen_active) ast_deactivate_generator(chan); @@ -664,6 +705,31 @@ } +int eivr_connect_socket(struct ast_channel *chan, const char *host, int port) +{ + int unit = -1; + struct sockaddr_in sin; + struct ast_hostent hp; + + if (ast_gethostbyname(host, &hp) == NULL) goto exit; + bzero((char *)&sin, sizeof(sin)); + sin.sin_family = AF_INET; + bcopy((char *)hp.hp.h_addr, + (char *)&sin.sin_addr.s_addr, + hp.hp.h_length); + sin.sin_port = htons(port); + + if ((unit=socket(AF_INET,SOCK_STREAM,0)) < 0) goto exit; + if (connect(unit,&sin,sizeof(sin)) < 0) { + unit = -1; + goto exit; + } + + +exit: + return(unit); + +} static int unload_module(void) {