[asterisk-commits] jpeeler: trunk r108404 - /trunk/apps/app_externalivr.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Mar 13 13:59:04 CDT 2008
Author: jpeeler
Date: Thu Mar 13 13:59:04 2008
New Revision: 108404
URL: http://svn.digium.com/view/asterisk?view=rev&rev=108404
Log:
(closes issue #11827)
Reported by: ctooley
Patches:
eivr_tcp_generic.patch uploaded by jpeeler (license 325)
This change adds the ability to communicate over a TCP socket instead of forking a child process.
Modified:
trunk/apps/app_externalivr.c
Modified: trunk/apps/app_externalivr.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_externalivr.c?view=diff&rev=108404&r1=108403&r2=108404
==============================================================================
--- trunk/apps/app_externalivr.c (original)
+++ trunk/apps/app_externalivr.c Thu Mar 13 13:59:04 2008
@@ -45,6 +45,7 @@
#include "asterisk/linkedlists.h"
#include "asterisk/app.h"
#include "asterisk/utils.h"
+#include "asterisk/tcptls.h"
static const char *app = "ExternalIVR";
@@ -88,6 +89,8 @@
static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u,
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)
@@ -305,6 +308,12 @@
int gen_active = 0;
int pid;
char *buf, *pipe_delim_argbuf, *pdargbuf_ptr;
+
+ char hostname[1024];
+ char *port_str = NULL;
+ int port = 0;
+ struct ast_tcptls_session_instance *ser;
+
struct ivr_localuser foo = {
.playlist = AST_LIST_HEAD_INIT_VALUE,
.finishlist = AST_LIST_HEAD_INIT_VALUE,
@@ -333,90 +342,137 @@
pipe_delim_argbuf = ast_strdupa(data);
while((pdargbuf_ptr = strchr(pipe_delim_argbuf, ',')) != NULL)
pdargbuf_ptr[0] = '|';
+
+ if(!strncmp(args.cmd[0], "ivr://", 6)) {
+ struct server_args ivr_desc = {
+ .accept_fd = -1,
+ .name = "IVR",
+ };
+ struct ast_hostent hp;
+
+ /*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*/
+
+ ast_gethostbyname(hostname, &hp);
+ ivr_desc.sin.sin_family = AF_INET;
+ ivr_desc.sin.sin_port = htons(port);
+ memmove(&ivr_desc.sin.sin_addr.s_addr, hp.hp.h_addr, hp.hp.h_length);
+ ser = ast_tcptls_client_start(&ivr_desc);
+
+ if (!ser) {
+ goto exit;
+ }
+ res = eivr_comm(chan, u, ser->fd, ser->fd, 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_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 (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;
- }
-
- 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 (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_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 (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;
+ }
+
+ 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);
+ }
+ }
+
+ exit:
+ if (gen_active)
+ ast_deactivate_generator(chan);
+
+ if (child_stdin[0])
close(child_stdin[0]);
- child_stdin[0] = 0;
+
+ if (child_stdin[1])
+ close(child_stdin[1]);
+
+ if (child_stdout[0])
+ close(child_stdout[0]);
+
+ if (child_stdout[1])
close(child_stdout[1]);
- child_stdout[1] = 0;
+
+ if (child_stderr[0])
+ close(child_stderr[0]);
+
+ if (child_stderr[1])
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);
-
- if (child_stdin[0])
- close(child_stdin[0]);
-
- if (child_stdin[1])
- close(child_stdin[1]);
-
- if (child_stdout[0])
- close(child_stdout[0]);
-
- if (child_stdout[1])
- close(child_stdout[1]);
-
- if (child_stderr[0])
- close(child_stderr[0]);
-
- if (child_stderr[1])
- close(child_stderr[1]);
-
- while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
- ast_free(entry);
-
- return res;
- }
+
+ if (ser) {
+ fclose(ser->f);
+ ast_tcptls_session_instance_destroy(ser);
+ }
+
+ while ((entry = AST_LIST_REMOVE_HEAD(&u->playlist, list)))
+ ast_free(entry);
+
+ return res;
}
static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u,
@@ -436,21 +492,21 @@
FILE *eivr_commands = NULL;
FILE *eivr_errors = NULL;
FILE *eivr_events = NULL;
-
- if (!(eivr_events = fdopen(eivr_events_fd, "w"))) {
- ast_chan_log(LOG_WARNING, chan, "Could not open stream to send events\n");
- goto exit;
- }
- if (!(eivr_commands = fdopen(eivr_commands_fd, "r"))) {
- ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive commands\n");
- goto exit;
- }
- if(eivr_errors_fd) { /*if opening a socket connection, error stream will not be used*/
+
+ if (!(eivr_events = fdopen(eivr_events_fd, "w"))) {
+ ast_chan_log(LOG_WARNING, chan, "Could not open stream to send events\n");
+ goto exit;
+ }
+ if (!(eivr_commands = fdopen(eivr_commands_fd, "r"))) {
+ ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive commands\n");
+ goto exit;
+ }
+ if(eivr_errors_fd) { /* if opening a socket connection, error stream will not be used */
if (!(eivr_errors = fdopen(eivr_errors_fd, "r"))) {
ast_chan_log(LOG_WARNING, chan, "Could not open stream to receive errors\n");
goto exit;
}
- }
+ }
setvbuf(eivr_events, NULL, _IONBF, 0);
setvbuf(eivr_commands, NULL, _IONBF, 0);
@@ -633,18 +689,18 @@
exit:
- if (eivr_events)
+ if (eivr_events)
fclose(eivr_events);
- if (eivr_commands)
+ if (eivr_commands)
fclose(eivr_commands);
- if (eivr_errors)
- fclose(eivr_errors);
+ if (eivr_errors)
+ fclose(eivr_errors);
return res;
- }
+}
static int unload_module(void)
{
More information about the asterisk-commits
mailing list