[Freeswitch-svn] [commit] r3917 - in freeswitch/trunk: scripts/socket scripts/socket/FreeSWITCH src src/include src/mod/event_handlers/mod_event_socket
Freeswitch SVN
anthm at freeswitch.org
Sat Jan 6 12:06:18 EST 2007
Author: anthm
Date: Sat Jan 6 12:06:18 2007
New Revision: 3917
Added:
freeswitch/trunk/scripts/socket/sock.pl (contents, props changed)
Modified:
freeswitch/trunk/scripts/socket/FreeSWITCH/Client.pm
freeswitch/trunk/src/include/switch_ivr.h
freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
freeswitch/trunk/src/switch_ivr.c
Log:
don't call us we'll call you
Modified: freeswitch/trunk/scripts/socket/FreeSWITCH/Client.pm
==============================================================================
--- freeswitch/trunk/scripts/socket/FreeSWITCH/Client.pm (original)
+++ freeswitch/trunk/scripts/socket/FreeSWITCH/Client.pm Sat Jan 6 12:06:18 2007
@@ -13,8 +13,11 @@
$self->{_host} = $args->{-host} || "localhost";
$self->{_port} = $args->{-port} || 8021;
$self->{_password} = $args->{-password} || undef;
-
+ $self->{events} = [];
my $me = bless $self,$class;
+ if (!$self->{_password}) {
+ return $me;
+ }
if ($me->connect()) {
return $me;
} else {
@@ -22,61 +25,62 @@
}
}
-sub input($;$) {
+sub readhash($;$) {
my ($self,$to) = @_;
- my $i;
- my @r;
- my $s = $self->{_sock};
- my $x = 0;
- my $done = 0;
- my $start = time;
-
- while(!$done) {
- if ($to and time - $start > $to) {
- last;
- }
- @ready = $self->{_sel}->can_read($to);
- if (@ready) {
- $x=0;
- foreach my $s (@ready) {
- while ($i = <$s>) {
- $x++;
- return @r if($i eq "\n");
- $i =~ s/[\n]+$//g;
- push @r,$i;
-
- }
- unless($x) {
- return ("SocketError: yes");
+ my ($can_read) = IO::Select::select($self->{_sel}, undef, undef, $to ? to : undef);
+ my $s = shift @{$can_read};
+ my @r = ();
+ my $crc = 0;
+ my $h;
+
+ if ($s) {
+ for (;;) {
+ my $line;
+ for (;;) {
+ my $i = 0;
+ recv $s, $i, 1, 0;
+ if ($i eq "") {
+ $h->{socketerror} = "yes";
+ return $h;
+ last;
+ } elsif ($i eq "\n") {
+ $crc++;
+ last;
+ } else {
+ $crc = 0;
}
+ $line .= $i;
+ }
+ if (!$line) {
+ last;
}
+ push @r, $line;
+ }
+
+ if (!@r) {
+ return undef;
}
- }
- return @r;
-
-}
-
-sub readhash($$) {
- my $self = shift;
- my $arg = shift;
-
- my @r = $self->input($arg);
- my $data = join "\n", @r;
- my %h = $data =~ /^([^:]+)\s*:\s*([^\n]*)/mg;
+ foreach(@r) {
+ my ($var, $val) = /^([^:]+):[\s\t]*(.*)$/;
+ $h->{lc $var} = $val;
+ }
+
+ if ($h->{'content-length'}) {
+ recv $s, $h->{body}, $h->{'content-length'}, 0;
+ }
- foreach (keys %h) {
- my $new = lc $_;
- $h{$new} = $h{$_};
- delete $h{$_};
+ if ($h->{'content-type'} eq "text/event-plain") {
+ my $e = $self->extract_event($h);
+ $h->{has_event} = 1;
+ $h->{event} = $e;
+ }
}
+
- if ($h{'content-length'}) {
- my $s = $self->{_sock};
- read $s, $h{body}, $h{'content-length'};
- }
- return \%h;
+ return $h;
+
}
sub error($$) {
@@ -92,31 +96,147 @@
print $s $data ;
}
-sub cmd($$$) {
+sub get_events($) {
my $self = shift;
- my $cmd = shift;
+ my $e = $self->{events};
+ $self->{events} = [];
+ return $e;
+}
+
+sub sendmsg($$$) {
+ my $self = shift;
+ my $sendmsg = shift;
my $to = shift;
+ my $e;
- $self->output($cmd->{command});
- foreach(keys %{$cmd}) {
+ for(;;) {
+ $e = $self->readhash(.1);
+ if ($e && !$e->{socketerror}) {
+ #print Dumper $e;
+ push @{$self->{events}}, $e;
+ } else {
+ last;
+ }
+ }
+
+ $self->output($sendmsg->{command} . "\n");
+ foreach(keys %{$sendmsg}) {
next if ($_ eq "command");
- $self->output($cmd->{$_});
+ $self->output("$_" . ": " . $sendmsg->{$_} . "\n");
}
- $self->output("\n\n");
+ $self->output("\n");
+
+ return $self->readhash($to);
+}
+
+sub command($$) {
+ my $self = shift;
+ my $reply;
- my $h = $self->readhash($to);
+ my $r = $self->sendmsg({ 'command' => "api " . shift });
- $h;
+ if ($r->{body}) {
+ $reply = $r->{body};
+ } else {
+ $reply = "socketerror";
+ }
+
+ return $reply;
}
sub disconnect($) {
my $self = shift;
- $self->{_sock}->shutdown(2);
- $self->{_sock}->close();
+ if ($self->{_sock}) {
+ $self->{_sock}->shutdown(2);
+ $self->{_sock}->close();
+ }
undef $self->{_sock};
delete $self->{_sock};
}
+sub raw_command($) {
+ my $self = shift;
+ return $self->sendmsg({ 'command' => shift });
+}
+
+sub htdecode($;$) {
+ my $urlin = shift;
+ my $url = (ref $urlin) ? \$$urlin : \$urlin;
+ $$url =~ s/%([0-9A-Z]{2})/chr hex $1/ieg;
+ $$url;
+}
+
+
+sub extract_event($$) {
+ my $self = shift;
+ my $r = shift;
+
+
+ my %h = $r->{body} =~ /^([^:]+)\s*:\s*([^\n]*)/mg;
+
+ foreach (keys %h) {
+ my $new = lc $_;
+ $h{$new} = $h{$_};
+ delete $h{$_};
+ }
+ foreach(keys %h) {
+ htdecode(\$h{$_});
+ }
+ return \%h;
+}
+
+
+sub call_command($$$) {
+ my $self = shift;
+ my $app = shift;
+ my $arg = shift;
+
+ my $hash = {
+ 'command' => "sendmsg",
+ 'call-command' => "execute",
+ 'execute-app-name' => $app,
+ 'execute-app-arg' => $arg
+ };
+
+ return $self->sendmsg($hash);
+}
+
+sub call_data($) {
+ my $self = shift;
+
+ return $self->{call_data};
+}
+
+sub accept($;$$) {
+ my $self = shift;
+ my $ip = shift;
+ my $port = shift || 8084;
+
+ if (!$self->{_lsock}) {
+ $self->{_lsock} = IO::Socket::INET->new(Listen => 10000,
+ LocalAddr => $ip,
+ LocalPort => $port,
+ Reuse => 1,
+ Proto => "tcp") or return $self->error("Cannot listen");
+
+ }
+
+ $self->{_sock} = $self->{_lsock}->accept();
+ $self->{_sock}->autoflush(1);
+ $self->{_sel} = new IO::Select( $self->{_sock} );
+
+ $self->{call_data} = $self->sendmsg({ 'command' => "connect"});
+ foreach(keys %{$self->{call_data}}) {
+ htdecode(\$self->{call_data}->{$_});
+ }
+ if ($self->{call_data} =~ /socketerror/) {
+ return 0;
+ }
+
+ return 1;
+
+};
+
sub connect($) {
my $self = shift;
@@ -134,7 +254,7 @@
if ($h->{"content-type"} eq "auth/request") {
my $pass = $self->{"_password"};
- $h = $self->cmd({command => "auth $pass"});
+ $h = $self->sendmsg({command => "auth $pass"});
}
if ($h->{'reply-text'} =~ "OK") {
Added: freeswitch/trunk/scripts/socket/sock.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/socket/sock.pl Sat Jan 6 12:06:18 2007
@@ -0,0 +1,45 @@
+#!/usr/bin/perl
+use FreeSWITCH::Client;
+use Data::Dumper;
+
+my $fs = init FreeSWITCH::Client {} or die "Error $@";
+my $pid;
+
+for (;;) {
+ $fs->accept();
+
+ if (!($pid = fork)) {
+ last;
+ }
+}
+
+my $data = $fs->call_data();
+
+#print Dumper $data
+print "Call: $data->{'caller-channel-name'} $data->{'unique-id'}\n";
+
+
+$o = $fs->call_command("answer");
+#to turn on events when in async mode
+#$o = $fs->raw_command("myevents");
+$o = $fs->call_command("playback", "/ram/swimp.raw");
+$o = $fs->call_command("hangup");
+
+#comment exit in async mode
+exit;
+
+while(my $r = $fs->readhash(undef)) {
+ if ($r->{socketerror}) {
+ last;
+ }
+
+ if ($r->{has_event}) {
+ print Dumper $r->{event};
+ }
+
+}
+
+$fs->disconnect();
+print "done\n";
+
+
Modified: freeswitch/trunk/src/include/switch_ivr.h
==============================================================================
--- freeswitch/trunk/src/include/switch_ivr.h (original)
+++ freeswitch/trunk/src/include/switch_ivr.h Sat Jan 6 12:06:18 2007
@@ -53,6 +53,14 @@
/*!
+ \brief Parse command from an event
+ \param session the session to send the message to
+ \param event the event to send
+ \return SWITCH_STATUS_SUCCESS if successful
+*/
+SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event);
+
+/*!
\brief Wait for time to pass for a specified number of milliseconds
\param session the session to wait for.
\param ms the number of milliseconds
Modified: freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
==============================================================================
--- freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c (original)
+++ freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c Sat Jan 6 12:06:18 2007
@@ -39,7 +39,11 @@
LFLAG_AUTHED = (1 << 0),
LFLAG_RUNNING = (1 << 1),
LFLAG_EVENTS = (1 << 2),
- LFLAG_LOG = (1 << 3)
+ LFLAG_LOG = (1 << 3),
+ LFLAG_FULL = (1 << 4),
+ LFLAG_MYEVENTS = (1 << 5),
+ LFLAG_SESSION = (1 << 6),
+ LFLAG_ASYNC = (1 << 7)
} event_flag_t;
typedef enum {
@@ -60,6 +64,7 @@
uint8_t event_list[SWITCH_EVENT_ALL+1];
switch_hash_t *event_hash;
switch_thread_rwlock_t *rwlock;
+ switch_core_session_t *session;
struct listener *next;
};
@@ -83,6 +88,9 @@
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_ip, prefs.ip)
SWITCH_DECLARE_GLOBAL_STRING_FUNC(set_pref_pass, prefs.password)
+static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj);
+static void launch_listener_thread(listener_t *listener);
+
static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_level_t level)
{
listener_t *l;
@@ -122,7 +130,7 @@
continue;
}
- if (l->event_list[(uint8_t)SWITCH_EVENT_ALL]) {
+ if (l->event_list[(uint8_t)SWITCH_EVENT_ALL]) {
send = 1;
} else if ((l->event_list[(uint8_t)event->event_id])) {
if (event->event_id != SWITCH_EVENT_CUSTOM || (event->subclass && switch_core_hash_find(l->event_hash, event->subclass->name))) {
@@ -130,6 +138,13 @@
}
}
+ if (send && switch_test_flag(l, LFLAG_MYEVENTS)) {
+ char *uuid = switch_event_get_header(event, "unique-id");
+ if (!uuid || strcmp(uuid, switch_core_session_get_uuid(l->session))) {
+ send = 1;
+ }
+ }
+
if (send) {
if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) {
switch_queue_push(l->event_queue, clone);
@@ -142,6 +157,105 @@
switch_mutex_unlock(listen_list.mutex);
}
+static void socket_function(switch_core_session_t *session, char *data)
+{
+ char *host, *port_name;
+ switch_socket_t *new_sock;
+ switch_sockaddr_t *sa;
+ int port = 8084;
+ listener_t *listener;
+ int argc = 0, x = 0;
+ char *argv[80] = {0};
+ char *mydata;
+
+ if (data && (mydata = switch_core_session_strdup(session, data))) {
+ argc = switch_separate_string(mydata, ' ', argv, (sizeof(argv) / sizeof(argv[0])));
+ }
+
+ if (argc < 1) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Parse Error!\n");
+ return;
+ }
+
+ host = argv[0];
+
+ if (switch_strlen_zero(host)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missing Host!\n");
+ return;
+ }
+
+ if ((port_name = strchr(host, ':'))) {
+ *port_name++ = '\0';
+ port = atoi(port_name);
+ }
+
+ if (switch_sockaddr_info_get(&sa, host, AF_INET, port, 0, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error!\n");
+ return;
+ }
+
+ if (switch_socket_create(&new_sock, AF_INET, SOCK_STREAM, APR_PROTO_TCP, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error!\n");
+ return;
+ }
+
+ switch_socket_opt_set(new_sock, SWITCH_SO_KEEPALIVE, 1);
+
+ if (switch_socket_connect(new_sock, sa) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Socket Error!\n");
+ return;
+ }
+
+
+ if (!(listener = switch_core_session_alloc(session, sizeof(*listener)))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error\n");
+ return;
+ }
+
+ switch_thread_rwlock_create(&listener->rwlock, switch_core_session_get_pool(session));
+ switch_queue_create(&listener->event_queue, SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
+ switch_queue_create(&listener->log_queue, SWITCH_CORE_QUEUE_LEN, switch_core_session_get_pool(session));
+
+ listener->sock = new_sock;
+ listener->pool = switch_core_session_get_pool(session);
+ listener->format = EVENT_FORMAT_PLAIN;
+ listener->session = session;
+
+ switch_mutex_init(&listener->flag_mutex, SWITCH_MUTEX_NESTED, listener->pool);
+ switch_core_hash_init(&listener->event_hash, listener->pool);
+ switch_set_flag(listener, LFLAG_AUTHED);
+ for(x = 1; x < argc; x++) {
+ if (argv[x] && !strcasecmp(argv[x], "full")) {
+ switch_set_flag(listener, LFLAG_FULL);
+ } else if (argv[x] && !strcasecmp(argv[x], "async")) {
+ switch_set_flag(listener, LFLAG_ASYNC);
+ }
+ }
+
+ if (switch_test_flag(listener, LFLAG_ASYNC)) {
+ launch_listener_thread(listener);
+ switch_ivr_park(session);
+ } else {
+ listener_run(NULL, (void*) listener);
+ }
+
+ while(switch_test_flag(listener, LFLAG_SESSION)) {
+ switch_yield(100000);
+ }
+
+}
+
+
+static const switch_application_interface_t socket_application_interface = {
+ /*.interface_name */ "socket",
+ /*.application_function */ socket_function,
+ /* long_desc */ "Connect to a socket",
+ /* short_desc */ "Connect to a socket",
+ /* syntax */ "<ip>[:<port>]",
+ /*.next */ NULL
+};
+
+
static switch_loadable_module_interface_t event_socket_module_interface = {
/*.module_name */ modname,
@@ -149,7 +263,7 @@
/*.timer_interface */ NULL,
/*.dialplan_interface */ NULL,
/*.codec_interface */ NULL,
- /*.application_interface */ NULL
+ /*.application_interface */ &socket_application_interface
};
@@ -255,6 +369,11 @@
return SWITCH_STATUS_FALSE;
}
+ if (listener->session && !switch_channel_ready(switch_core_session_get_channel(listener->session))) {
+ status = SWITCH_STATUS_FALSE;
+ break;
+ }
+
if (mlen) {
bytes += mlen;
do_sleep = 0;
@@ -313,7 +432,7 @@
break;
}
}
-
+
if (timeout) {
elapsed = (uint32_t)(time(NULL) - start);
if (elapsed >= timeout) {
@@ -493,6 +612,53 @@
}
+ if (listener->session) {
+ if (!strncasecmp(cmd, "connect", 7)) {
+ snprintf(reply, reply_len, "+OK");
+ goto done;
+ } else if (!strncasecmp(cmd, "sendmsg", 4)) {
+ if (switch_test_flag(listener, LFLAG_ASYNC)) {
+ if ((status = switch_core_session_queue_private_event(listener->session, &event)) == SWITCH_STATUS_SUCCESS) {
+ snprintf(reply, reply_len, "+OK");
+ } else {
+ snprintf(reply, reply_len, "-ERR memory error");
+ }
+ } else {
+ switch_ivr_parse_event(listener->session, event);
+ snprintf(reply, reply_len, "+OK");
+ }
+ goto done;
+ } else if (!strncasecmp(cmd, "myevents", 8)) {
+ listener->event_list[SWITCH_EVENT_CHANNEL_CREATE] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_DESTROY] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_STATE] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_ANSWER] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_HANGUP] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_EXECUTE] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_BRIDGE] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_UNBRIDGE] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_PROGRESS] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_OUTGOING] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_PARK] = 1;
+ listener->event_list[SWITCH_EVENT_CHANNEL_UNPARK] = 1;
+ listener->event_list[SWITCH_EVENT_TALK] = 1;
+ listener->event_list[SWITCH_EVENT_DTMF] = 1;
+ listener->event_list[SWITCH_EVENT_NOTALK] = 1;
+ listener->event_list[SWITCH_EVENT_DETECTED_SPEECH] = 1;
+ switch_set_flag_locked(listener, LFLAG_MYEVENTS);
+ switch_set_flag_locked(listener, LFLAG_EVENTS);
+ if (strstr(cmd, "xml") || strstr(cmd, "XML")) {
+ listener->format = EVENT_FORMAT_XML;
+ }
+ snprintf(reply, reply_len, "+OK Events Enabled");
+ goto done;
+ }
+
+ if (!switch_test_flag(listener, LFLAG_FULL)) {
+ goto done;
+ }
+ }
+
if (!strncasecmp(cmd, "sendevent", 9)) {
char *ename;
strip_cr(cmd);
@@ -798,42 +964,92 @@
switch_status_t status;
switch_event_t *event;
char reply[512] = "";
+ switch_core_session_t *session = NULL;
+ switch_channel_t *channel = NULL;
+
assert(listener != NULL);
+ if ((session = listener->session)) {
+ channel = switch_core_session_get_channel(session);
+ switch_core_session_read_lock(session);
+ }
+
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Open\n");
switch_socket_opt_set(listener->sock, APR_SO_NONBLOCK, TRUE);
switch_set_flag_locked(listener, LFLAG_RUNNING);
add_listener(listener);
- snprintf(buf, sizeof(buf), "Content-Type: auth/request\n\n");
+ if (session && switch_test_flag(listener, LFLAG_AUTHED)) {
+ switch_event_t *event = NULL, *call_event;
+ char *event_str;
+
+
+ switch_set_flag_locked(listener, LFLAG_SESSION);
+ status = read_packet(listener, &event, 25);
+
+ if (status != SWITCH_STATUS_SUCCESS || !event) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Socket Error!\n");
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ goto done;
+ }
+
+ if (switch_event_create(&call_event, SWITCH_EVENT_MESSAGE) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ goto done;
+ }
+
+ if (parse_command(listener, event, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ goto done;
+ }
+
+ switch_caller_profile_event_set_data(switch_channel_get_caller_profile(channel), "Channel", call_event);
+ switch_channel_event_set_data(channel, call_event);
+ switch_event_add_header(call_event, SWITCH_STACK_BOTTOM, "Content-Type", "command/reply");
+
+ switch_event_add_header(call_event, SWITCH_STACK_BOTTOM, "Socket-Mode", switch_test_flag(listener, LFLAG_ASYNC) ? "async" : "static");
+ switch_event_add_header(call_event, SWITCH_STACK_BOTTOM, "Control", switch_test_flag(listener, LFLAG_FULL) ? "full" : "single-channel");
+
+ switch_event_serialize(call_event, &event_str);
+ if (!event_str) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ goto done;
+ }
+ len = strlen(event_str);
+ switch_socket_send(listener->sock, event_str, &len);
+
+ switch_safe_free(event_str);
+ } else {
+ snprintf(buf, sizeof(buf), "Content-Type: auth/request\n\n");
- len = strlen(buf);
- switch_socket_send(listener->sock, buf, &len);
+ len = strlen(buf);
+ switch_socket_send(listener->sock, buf, &len);
+ while (!switch_test_flag(listener, LFLAG_AUTHED)) {
+ status = read_packet(listener, &event, 25);
+ if (status != SWITCH_STATUS_SUCCESS) {
+ goto done;
+ }
+ if (!event) {
+ continue;
+ }
- while (!switch_test_flag(listener, LFLAG_AUTHED)) {
-
- status = read_packet(listener, &event, 25);
- if (status != SWITCH_STATUS_SUCCESS) {
- goto done;
- }
- if (!event) {
- continue;
- }
- if (parse_command(listener, event, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
- switch_clear_flag_locked(listener, LFLAG_RUNNING);
- goto done;
- }
- if (!switch_strlen_zero(reply)) {
- snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
- len = strlen(buf);
- switch_socket_send(listener->sock, buf, &len);
- }
- break;
- }
-
+ if (parse_command(listener, event, reply, sizeof(reply)) != SWITCH_STATUS_SUCCESS) {
+ switch_clear_flag_locked(listener, LFLAG_RUNNING);
+ goto done;
+ }
+ if (!switch_strlen_zero(reply)) {
+ snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
+ len = strlen(buf);
+ switch_socket_send(listener->sock, buf, &len);
+ }
+ break;
+ }
+ }
while(switch_test_flag(listener, LFLAG_RUNNING) && listen_list.ready) {
switch_event_t *event;
@@ -855,7 +1071,6 @@
break;
}
-
if (!switch_strlen_zero(reply)) {
snprintf(buf, sizeof(buf), "Content-Type: command/reply\nReply-Text: %s\n\n", reply);
len = strlen(buf);
@@ -869,25 +1084,23 @@
remove_listener(listener);
close_socket(&listener->sock);
- if (switch_test_flag(listener, LFLAG_EVENTS)) {
- remove_listener(listener);
- }
-
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Thread done, waiting for children\n");
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Session complete, waiting for children\n");
switch_thread_rwlock_wrlock(listener->rwlock);
switch_thread_rwlock_unlock(listener->rwlock);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connection Closed\n");
-
-
- if (listener->pool) {
+ if (session) {
+ switch_channel_clear_flag(switch_core_session_get_channel(session), CF_CONTROLLED);
+ switch_clear_flag_locked(listener, LFLAG_SESSION);
+ switch_core_session_rwunlock(session);
+ } else if (listener->pool) {
switch_memory_pool_t *pool = listener->pool;
switch_core_destroy_memory_pool(&pool);
}
+
return NULL;
}
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Sat Jan 6 12:06:18 2007
@@ -86,7 +86,7 @@
}
-static void switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event)
+SWITCH_DECLARE(switch_status_t) switch_ivr_parse_event(switch_core_session_t *session, switch_event_t *event)
{
switch_channel_t *channel = switch_core_session_get_channel(session);
char *cmd = switch_event_get_header(event, "call-command");
@@ -97,40 +97,47 @@
unsigned long CMD_NOMEDIA = apr_hashfunc_default("nomedia", &hlen);
assert(channel != NULL);
+
+ if (switch_strlen_zero(cmd)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Command!\n");
+ return SWITCH_STATUS_FALSE;
+ }
+
hlen = (switch_size_t) strlen(cmd);
cmd_hash = apr_hashfunc_default(cmd, &hlen);
switch_channel_set_flag(channel, CF_EVENT_PARSE);
- if (!switch_strlen_zero(cmd)) {
- if (cmd_hash == CMD_EXECUTE) {
- const switch_application_interface_t *application_interface;
- char *app_name = switch_event_get_header(event, "execute-app-name");
- char *app_arg = switch_event_get_header(event, "execute-app-arg");
+
+ if (cmd_hash == CMD_EXECUTE) {
+ const switch_application_interface_t *application_interface;
+ char *app_name = switch_event_get_header(event, "execute-app-name");
+ char *app_arg = switch_event_get_header(event, "execute-app-arg");
- if (app_name && app_arg) {
- if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
- if (application_interface->application_function) {
- application_interface->application_function(session, app_arg);
- }
- }
- }
- } else if (cmd_hash == CMD_HANGUP) {
- char *cause_name = switch_event_get_header(event, "hangup-cause");
- switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
-
- if (cause_name) {
- cause = switch_channel_str2cause(cause_name);
- }
+ if (app_name && app_arg) {
+ if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
+ if (application_interface->application_function) {
+ application_interface->application_function(session, app_arg);
+ }
+ }
+ }
+ } else if (cmd_hash == CMD_HANGUP) {
+ char *cause_name = switch_event_get_header(event, "hangup-cause");
+ switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
- switch_channel_hangup(channel, cause);
- } else if (cmd_hash == CMD_NOMEDIA) {
- char *uuid = switch_event_get_header(event, "nomedia-uuid");
- switch_ivr_nomedia(uuid, SMF_REBRIDGE);
- }
- }
+ if (cause_name) {
+ cause = switch_channel_str2cause(cause_name);
+ }
+
+ switch_channel_hangup(channel, cause);
+ } else if (cmd_hash == CMD_NOMEDIA) {
+ char *uuid = switch_event_get_header(event, "nomedia-uuid");
+ switch_ivr_nomedia(uuid, SMF_REBRIDGE);
+ }
+
switch_channel_clear_flag(channel, CF_EVENT_PARSE);
+ return SWITCH_STATUS_SUCCESS;
}
@@ -153,7 +160,7 @@
}
switch_channel_set_flag(channel, CF_CONTROLLED);
- while (switch_channel_ready(channel)) {
+ while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_CONTROLLED)) {
if ((status = switch_core_session_read_frame(session, &frame, -1, stream_id)) == SWITCH_STATUS_SUCCESS) {
if (!SWITCH_READ_ACCEPTABLE(status)) {
@@ -164,6 +171,16 @@
switch_ivr_parse_event(session, event);
switch_event_destroy(&event);
}
+
+ if (switch_channel_has_dtmf(channel)) {
+ char dtmf[128];
+ switch_channel_dequeue_dtmf(channel, dtmf, sizeof(dtmf));
+ }
+
+ if (switch_core_session_dequeue_event(session, &event) == SWITCH_STATUS_SUCCESS) {
+ switch_channel_event_set_data(channel, event);
+ switch_event_fire(&event);
+ }
}
}
@@ -4597,27 +4614,7 @@
done = 1;
break;
} else if (!strcasecmp(func, "execute")) {
- const switch_application_interface_t *application_interface;
- char *app_name = NULL;
- char *app_arg = NULL;
-
- if ((app_name = strdup(odata))) {
- char *e = NULL;
- if ((app_arg = strchr(app_name, '('))) {
- *app_arg++ = '\0';
- if ((e = strchr(app_arg, ')'))) {
- *e = '\0';
- }
- if (app_name && app_arg && e && (application_interface = switch_loadable_module_get_application_interface(app_name))) {
- if (application_interface->application_function) {
- application_interface->application_function(session, app_arg);
- }
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Application!\n");
- }
- }
- switch_safe_free(app_name);
- }
+
} else if (!strcasecmp(func, "say")) {
switch_say_interface_t *si;
if ((si = switch_loadable_module_get_say_interface(lang))) {
More information about the Freeswitch-svn
mailing list