提交 9d1e2e91 authored 作者: Anthony Minessale's avatar Anthony Minessale

don't call us we'll call you

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@3917 d0543943-73ff-0310-b7d9-9358b9ac24b2
上级 aa2d884d
......@@ -13,8 +13,11 @@ sub init($;$) {
$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 init($;$) {
}
}
sub input($;$) {
sub readhash($;$) {
my ($self,$to) = @_;
my $i;
my @r;
my $s = $self->{_sock};
my $x = 0;
my $done = 0;
my $start = time;
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;
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");
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 @@ sub output($$) {
print $s $data ;
}
sub cmd($$$) {
sub get_events($) {
my $self = shift;
my $e = $self->{events};
$self->{events} = [];
return $e;
}
sub sendmsg($$$) {
my $self = shift;
my $cmd = shift;
my $sendmsg = shift;
my $to = shift;
my $e;
for(;;) {
$e = $self->readhash(.1);
if ($e && !$e->{socketerror}) {
#print Dumper $e;
push @{$self->{events}}, $e;
} else {
last;
}
}
$self->output($cmd->{command});
foreach(keys %{$cmd}) {
$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 @@ sub connect($) {
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") {
......
#!/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";
......@@ -52,6 +52,14 @@ SWITCH_BEGIN_EXTERN_C
*/
/*!
\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.
......
......@@ -86,7 +86,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session,
}
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 @@ static void switch_ivr_parse_event(switch_core_session_t *session, switch_event_
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 (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 (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_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_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session)
}
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)) {
......@@ -163,6 +170,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_park(switch_core_session_t *session)
if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) {
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 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_phrase_macro(switch_core_session_t *s
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))) {
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论