Freeswitch-trunk
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
October 2006
- 5 participants
- 223 discussions
Author: mikej
Date: Fri Oct 20 02:28:39 2006
New Revision: 3117
Modified:
freeswitch/trunk/conf/freeswitch.xml
Log:
fix typo profile->profiles, unmatched tag.
Modified: freeswitch/trunk/conf/freeswitch.xml
==============================================================================
--- freeswitch/trunk/conf/freeswitch.xml (original)
+++ freeswitch/trunk/conf/freeswitch.xml Fri Oct 20 02:28:39 2006
@@ -113,7 +113,7 @@
</configuration>
<configuration name="sofia.conf" description="sofia Endpoint">
- <profile>
+ <profiles>
<profile name="mydomain1.com">
<registrations>
<!-- <registration name="asterlink">
1
0
[commit] r3116 - in freeswitch/trunk/scripts: POE-Filter-FSSocket POE-Filter-FSSocket/examples POE-Filter-FSSocket/lib POE-Filter-FSSocket/lib/POE POE-Filter-FSSocket/lib/POE/Filter POE-Filter-FSSocket/t socket
by Freeswitch SVN 20 Oct '06
by Freeswitch SVN 20 Oct '06
20 Oct '06
Author: ptinsley
Date: Fri Oct 20 02:20:39 2006
New Revision: 3116
Added:
freeswitch/trunk/scripts/POE-Filter-FSSocket/
freeswitch/trunk/scripts/POE-Filter-FSSocket/CHANGES
freeswitch/trunk/scripts/POE-Filter-FSSocket/INSTALL
freeswitch/trunk/scripts/POE-Filter-FSSocket/LICENSE
freeswitch/trunk/scripts/POE-Filter-FSSocket/Makefile.PL
freeswitch/trunk/scripts/POE-Filter-FSSocket/README
freeswitch/trunk/scripts/POE-Filter-FSSocket/TODO
freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/
freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/fsconsole.pl
freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/poetest.pl
freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/
freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/POE/
freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/POE/Filter/
freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/POE/Filter/FSSocket.pm (contents, props changed)
freeswitch/trunk/scripts/POE-Filter-FSSocket/t/
freeswitch/trunk/scripts/POE-Filter-FSSocket/t/01_basic.t
freeswitch/trunk/scripts/socket/fsconsole.pl
Log:
Initial checkin of the POE::Filter::FSSocket module and fsconsole.pl which is a curses, multi-window console for freeswitch mod_event_socket. See http://search.cpan.org/~ptinsley/POE-Filter-FSSocket-0.04/lib/POE/Filter/FS… for more info on the perl module.
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/CHANGES
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/CHANGES Fri Oct 20 02:20:39 2006
@@ -0,0 +1,50 @@
+=========================
+2006-10-14 00:08:00 v0_05
+=========================
+
+ 2006-10-14 00:08:00 (r5) by ptinsley
+
+ Added some "bullet proofing" in the module to handle bad/unknown input
+ Updated the curses example (fsconsole.pl)
+ Added debug and strict parsing as part of the bullet proofing
+ to enable debug add debug => 1 in your new() and if you want the module
+ to croak when it doesn't properly parse something use strict => 1 in the
+ new(). Example Poe::Filter::FSSocket->new(debug => 1, strict => 1)
+ The default for debug and strict is 0
+
+=========================
+2006-10-14 00:08:00 v0_04
+=========================
+
+ 2006-10-14 00:08:00 (r4) by ptinsley
+
+ Fixed support for log/data
+ Added an example that is a quick curses console for freeswitch
+
+=========================
+2006-09-18 21:08:00 v0_03
+=========================
+
+ 2006-09-18 21:08:00 (r3) by ptinsley
+
+ Added support for log/data
+
+=========================
+2006-09-17 23:57:00 v0_02
+=========================
+
+ 2006-09-17 23:57:00 (r2) by ptinsley
+
+ Added support for api/response type, data ends up in api-response variable.
+
+=========================
+2006-09-17 22:19:20 v0_01
+=========================
+
+ 2006-09-17 22:19:20 (r1) by ptinsley
+
+ Initial package of the module.
+
+==============
+End of Excerpt
+==============
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/INSTALL
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/INSTALL Fri Oct 20 02:20:39 2006
@@ -0,0 +1,4 @@
+perl Makefile.PL
+make
+make test
+make install
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/LICENSE
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/LICENSE Fri Oct 20 02:20:39 2006
@@ -0,0 +1,18 @@
+The contents of this file are subject to the Mozilla Public License
+Version 1.1 (the "License"); you may not use this file except in
+compliance with the License. You may obtain a copy of the License at
+http://www.mozilla.org/MPL/
+
+Software distributed under the License is distributed on an "AS IS"
+basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+License for the specific language governing rights and limitations
+under the License.
+
+The Original Code is POE::Filter::FSSocket.
+
+The Initial Developer of the Original Code is Paul Tinsley <pdt(a)jackhammer.org>.
+Portions created by the Initial Developer are Copyright (C) 2006
+the Initial Developer. All Rights Reserved.
+
+Contributor(s):
+ Paul Tinsley <pdt(a)jackhammer.org>
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/Makefile.PL
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/Makefile.PL Fri Oct 20 02:20:39 2006
@@ -0,0 +1,22 @@
+#!/usr/bin/perl
+
+use ExtUtils::MakeMaker;
+
+WriteMakefile(
+ NAME => 'POE::Filter::FSSocket',
+ AUTHOR => 'Paul Tinsley <pdt(a)jackhammer.org>',
+ ABSTRACT => 'POE filter for getting events out of FreeSWITCH',
+ VERSION_FROM => 'lib/POE/Filter/FSSocket.pm',
+
+ PM => { 'lib/POE/Filter/FSSocket.pm' => '$(INST_LIBDIR)/FSSocket.pm' },
+ PREREQ_PM => {
+ POE => 0.3101,
+ Test::More => 0,
+ POE::Component::Client::TCP => 0,
+ POE::Filter::Line => 0,
+ },
+ dist => {
+ COMPRESS => 'gzip -9f',
+ SUFFIX => 'gz',
+ },
+);
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/README
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/README Fri Oct 20 02:20:39 2006
@@ -0,0 +1,3 @@
+A POE filter for FreeSWITCH (http://www.freeswitch.org) that parses event/log/etc... messages for you. You must ask for events in plain mode.
+
+perldoc POE::Filter::FSSocket for more info and an example.
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/TODO
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/TODO Fri Oct 20 02:20:39 2006
@@ -0,0 +1,5 @@
+- Support bgapi output
+- more example scripts
+- more documentation
+- sister component that uses this filter
+- reconnect handling
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/fsconsole.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/fsconsole.pl Fri Oct 20 02:20:39 2006
@@ -0,0 +1,361 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+sub POE::Kernel::ASSERT_DEFAULT () { 1 };
+sub Term::Visual::DEBUG () { 1 }
+sub Term::Visual::DEBUG_FILE () { 'test.log' }
+use IO::Socket;
+use POE qw/Filter::FSSocket Component::Client::TCP/;
+use Data::Dumper;
+use Term::Visual;
+
+
+local *D;
+if (Term::Visual::DEBUG) {
+ *D = *Term::Visual::ERRS;
+}
+
+#local *ERROR = *STDERR;
+
+
+$SIG{__DIE__} = sub {
+ if (Term::Visual::DEBUG) {
+ print Term::Visual::ERRS "Died: @_\n";
+ }
+};
+
+###############################################################################
+## BEGIN Globals ##############################################################
+###############################################################################
+our $server_address = "127.0.0.1";
+our $server_port = "8021";
+our $server_secret = "ClueCon";
+
+#this is where you can customize the color scheme
+our %Pallet = (
+ 'warn_bullet' => 'bold yellow',
+ 'err_bullet' => 'bold red',
+ 'out_bullet' => 'bold green',
+ 'access' => 'bright red on blue',
+ 'current' => 'bright yellow on blue',
+);
+
+our $terminal;
+my %sockets;
+my %windows;
+my %unread_count;
+my %commands = (
+ 'window' => 1,
+ 'w' => 1,
+ 'win' => 1,
+);
+###############################################################################
+## END Globals ##############################################################
+###############################################################################
+
+#setup our session
+POE::Session->create(
+ 'inline_states' => {
+ '_start' => \&handle_start, #session start
+ '_stop' => \&handle_stop, #session stop
+ 'curses_input' => \&handle_curses_input, #input from the keyboard
+ 'update_time' => \&handle_update_time, #update the status line clock
+ 'quit' => \&handle_quit, #handler to do any cleanup
+ 'server_input' => \&handle_server_input,
+ '_default' => \&handle_default,
+ },
+ 'heap' => {
+ 'terminal' => undef,
+ 'freeswitch' => undef,
+ },
+);
+
+#start the kernel a chugging along
+$poe_kernel->run;
+
+###############################################################################
+## BEGIN Handlers #############################################################
+###############################################################################
+#handles any startup functions for our session
+sub handle_default {
+}
+
+sub handle_start {
+ my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
+
+ #setup our terminal
+ $heap->{'terminal'} = Term::Visual->new(
+ 'Alias' => 'terminal', #poe alias for this
+ 'History_Size' => 300, #number of things to keep in history
+ 'Common_Input' => 1, #all windows share input and history
+ 'Tab_Complete' => \&tab_complete,
+ );
+
+ $terminal = $heap->{'terminal'};
+
+ #setup the color palette
+ $terminal->set_palette(%Pallet);
+
+ #create a base window
+ my $window_id = $terminal->create_window(
+ 'Window_Name' => 'console',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Console',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'console'} = $window_id;
+
+ $window_id = $terminal->create_window(
+ 'Window_Name' => 'log',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Logs',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'log'} = $window_id;
+
+ $window_id = $terminal->create_window(
+ 'Window_Name' => 'event',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Event',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'event'} = $window_id;
+
+ #tell the terminal what to call when there is input from the keyboard
+ $kernel->post('terminal' => 'send_me_input' => 'curses_input');
+
+ $terminal->change_window(0);
+ $kernel->delay_set('update_time' => 1);
+ $terminal->set_status_field(0, 'time' => scalar(localtime));
+ new_message('destination_window' => 0, 'message' => "
+Welcome to the FreeSWITCH POE Curses Console!
+ The console is split into three windows:
+ - 'console' for api response messages
+ - 'log' for freeswitch log output (simply send the log level you want
+ to start seeing events eg: 'log all')
+ - 'event' for freeswitch event output (must subscribe in plain format
+ eg: 'event plain all')
+
+To switch between windows type 'w <windowname' so 'w log' for example.
+
+Coming soon:
+ - Tab completion
+ - command history
+ - window status in the bar (messages added since last view, etc...)
+
+Send any bug reports or comments to jackhammer\(a)gmail.com
+
+Thanks,
+Paul\n");
+
+ $terminal->set_status_field($terminal->current_window, 'window_status' => format_window_status());
+
+ #connect to freeswitch
+ $heap->{'freeswitch'} = POE::Component::Client::TCP->new(
+ 'RemoteAddress' => $server_address,
+ 'RemotePort' => $server_port,
+ 'ServerInput' => \&handle_server_input,
+ 'Connected' => \&handle_fs_connected,
+ 'ServerError' => \&handle_server_error,
+ 'Disconnected' => \&handle_server_disconnect,
+ 'Domain' => AF_INET,
+ 'Filter' => POE::Filter::FSSocket->new(),
+ );
+
+}
+
+#called when users enter commands in a window
+sub handle_curses_input {
+ my ($kernel, $heap, $input, $context) = @_[KERNEL, HEAP, ARG0, ARG1];
+
+ #get the id of the window that is responsible for the input
+ my $window = $heap->{'terminal'}->current_window;
+
+ open(ERROR, ">>error.log");
+
+ if($input eq "quit") {
+ $kernel->yield('quit');
+ } elsif ($input =~ /^w\ (.*)$/) {
+ #get the id of the requested window
+ eval {
+ my $window_id = $windows{$1};
+
+ #see if it's real
+ if(defined($window_id)) {
+ $unread_count{$window_id} = 0;
+ $terminal->change_window($window_id);
+ $terminal->set_status_field($window_id, 'window_status' => &format_window_status());
+ }
+ };
+ if($@) {
+ print ERROR "put error: $@\n";
+ }
+ } else {
+ #see if we got connected at some point
+ if(defined($sockets{'localhost'})) {
+ #send the command
+ $sockets{'localhost'}->put($input);
+ }
+ }
+}
+
+sub handle_fs_connected {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+ eval {
+ $sockets{'localhost'} = $heap->{'server'};
+ }
+}
+
+#this is responsible for doing any cleanup and returning the terminal to the previous
+#state before we mucked with it
+sub handle_quit {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+ #tell curses to clean up it's crap
+ $kernel->post('terminal' => 'shutdown');
+
+ #there is probably a more elegant way, but this works for now
+ exit;
+}
+
+#data from freeswitch
+sub handle_server_input {
+ my ($kernel,$heap,$input) = @_[KERNEL,HEAP,ARG0];
+
+ eval {
+ #terminal HATES null
+ if(defined($input->{'__DATA__'})) {
+ $input->{'__DATA__'} =~ s/[\x00]//g;
+ }
+
+ #handle the login
+ if($input->{'Content-Type'} eq "auth/request") {
+ $heap->{'server'}->put("auth $server_secret");
+ } elsif ($input->{'Content-Type'} eq "api/response") {
+ new_message('destination_window' => 0, 'message' => 'Response: ');
+ new_message('destination_window' => 0, 'message' => $input->{'__DATA__'});
+ } elsif ($input->{'Content-Type'} eq "log/data") {
+ new_message('destination_window' => 1, 'message' => $input->{'__DATA__'});
+ } elsif ($input->{'Content-Type'} eq "text/event-plain") {
+ new_message('destination_window' => 2, 'message' => Dumper $input);
+ }
+ };
+
+ if($@) {
+ open(ERROR, ">>error.log");
+ print ERROR "died: $@\n";
+ print ERROR Dumper $heap;
+ close(ERROR);
+ }
+}
+
+sub handle_server_error {
+}
+
+sub handle_server_disconnect {
+}
+
+sub tab_complete {
+ my $left = shift;
+
+ my @return;
+
+ if(defined($commands{$left})) {
+ return [$left . " "];
+ #} elsif () {
+ }
+
+}
+
+sub handle_update_time {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+ $terminal->set_status_field($terminal->current_window, 'time' => scalar(localtime));
+ $kernel->delay_set('update_time' => 1);
+}
+###############################################################################
+## END Handlers #############################################################
+###############################################################################
+
+sub new_message {
+ my %args = @_;
+
+ my $message = $args{'message'};
+ my $destination_window = $args{'destination_window'};
+
+ my $status_field;
+
+ #see if we are on the window being updated
+ if($terminal->current_window != $destination_window) {
+ #increment the unread count for the window
+ #FIXME, should we count messages or lines?
+ $unread_count{$destination_window}++;
+
+
+ #update the status bar
+ eval {
+ $terminal->set_status_field($terminal->current_window, 'window_status' => &format_window_status());
+ };
+
+ if($@) {
+ print $@;
+ }
+ }
+
+
+ #deliver the message
+ $terminal->print($destination_window, $message);
+}
+
+sub format_window_status {
+ my $status_field;
+
+ #put all the windows in the bar with their current unread count
+ foreach my $window (sort {$windows{$a} <=> $windows{$b}} keys %windows) {
+ #see if we are printing the current window
+ if($terminal->current_window == $windows{$window}) {
+ $status_field .= "[\0(current)$window\0(st_frames)";
+ } else {
+ $status_field .= "[$window";
+ }
+
+ if($unread_count{$windows{$window}}) {
+ $status_field .= " (" . $unread_count{$windows{$window}} . ")";
+ }
+
+ $status_field .= "] ";
+ }
+
+ return $status_field;
+}
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/poetest.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/examples/poetest.pl Fri Oct 20 02:20:39 2006
@@ -0,0 +1,42 @@
+#!/usr/bin/perl
+
+use warnings;
+use strict;
+
+use POE qw(Component::Client::TCP Filter::FSSocket);
+use Data::Dumper;
+
+my $auth_sent = 0;
+my $password = "ClueCon";
+
+POE::Component::Client::TCP->new(
+ 'RemoteAddress' => '127.0.0.1',
+ 'RemotePort' => '8021',
+ 'ServerInput' => \&handle_server_input,
+ 'Filter' => POE::Filter::FSSocket->new(),
+);
+
+POE::Kernel->run();
+exit;
+
+
+sub handle_server_input {
+ my ($heap,$input) = @_[HEAP,ARG0];
+
+ print Dumper $input;
+
+
+ if($input->{'Content-Type'} eq "auth/request") {
+ $auth_sent = 1;
+ $heap->{'server'}->put("auth $password");
+ } elsif ($input->{'Content-Type'} eq "command/reply") {
+ if($auth_sent == 1) {
+ $auth_sent = -1;
+
+ #do post auth stuff
+ $heap->{'server'}->put("events plain all");
+ $heap->{'server'}->put("log");
+ $heap->{'server'}->put("api show channels");
+ }
+ }
+}
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/POE/Filter/FSSocket.pm
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/lib/POE/Filter/FSSocket.pm Fri Oct 20 02:20:39 2006
@@ -0,0 +1,343 @@
+=head1 NAME
+
+POE::Filter::FSSocket - a POE filter that parses FreeSWITCH events into hashes
+
+=head1 SYNOPSIS
+
+ #!/usr/bin/perl
+
+ use warnings;
+ use strict;
+
+ use POE qw(Component::Client::TCP Filter::FSSocket);
+ use Data::Dumper;
+
+ my $auth_sent = 0;
+ my $password = "ClueCon";
+
+ POE::Component::Client::TCP->new(
+ 'RemoteAddress' => '127.0.0.1',
+ 'RemotePort' => '8021',
+ 'ServerInput' => \&handle_server_input,
+ 'Filter' => 'POE::Filter::FSSocket',
+ );
+
+ POE::Kernel->run();
+ exit;
+
+ sub handle_server_input {
+ my ($heap,$input) = @_[HEAP,ARG0];
+
+ print Dumper $input;
+
+
+ if($input->{'Content-Type'} eq "auth/request") {
+ $auth_sent = 1;
+ $heap->{'server'}->put("auth $password");
+ } elsif ($input->{'Content-Type'} eq "command/reply") {
+ if($auth_sent == 1) {
+ $auth_sent = -1;
+
+ #do post auth stuff
+ $heap->{'server'}->put("events plain all");
+ }
+ }
+ }
+
+=head1 EXAMPLES
+
+See examples in the examples directory of the distribution.
+
+=head1 DESCRIPTION
+
+POE::Filter::FSSocket parses output from FreeSWITCH into hashes. FreeSWITCH
+events have a very wide range of keys, the only consistant one being
+Content-Type. The keys are dependant on the type of events. You must use the
+plain event type as that is what the filter knows how to parse. You can ask for
+as many event types as you like or all for everything. You specify a list of
+event types by putting spaces between them ex: "events plain api log talk"
+
+Currently known event types (Event-Name):
+
+ CUSTOM
+ CHANNEL_CREATE
+ CHANNEL_DESTROY
+ CHANNEL_STATE
+ CHANNEL_ANSWER
+ CHANNEL_HANGUP
+ CHANNEL_EXECUTE
+ CHANNEL_BRIDGE
+ CHANNEL_UNBRIDGE
+ CHANNEL_PROGRESS
+ CHANNEL_OUTGOING
+ CHANNEL_PARK
+ CHANNEL_UNPARK
+ API
+ LOG
+ INBOUND_CHAN
+ OUTBOUND_CHAN
+ STARTUP
+ SHUTDOWN
+ PUBLISH
+ UNPUBLISH
+ TALK
+ NOTALK
+ SESSION_CRASH
+ MODULE_LOAD
+ DTMF
+ MESSAGE
+ CODEC
+ BACKGROUND_JOB
+ ALL
+
+Currently handled FreeSWITCH messages (Content-Type):
+
+ auth/request
+ command/response
+ text/event-plain
+ api/response (data in __DATA__ variable)
+ log/data (data in __DATA__ variable)
+
+=cut
+
+
+package POE::Filter::FSSocket;
+
+use warnings;
+use strict;
+
+use Carp qw(carp croak);
+use vars qw($VERSION);
+use base qw(POE::Filter);
+
+$VERSION = '0.05';
+
+use POE::Filter::Line;
+use Data::Dumper;
+
+#self array
+sub LINE_FILTER() {1}
+sub PARSER_STATE() {2}
+sub PARSER_STATENEXT() {3}
+sub PARSED_RECORD() {4}
+sub CURRENT_LENGTH() {5}
+sub STRICT_PARSE() {6}
+sub DEBUG_LEVEL() {7}
+
+#states of the parser
+sub STATE_WAITING() {1} #looking for new input
+sub STATE_CLEANUP() {2} #wipe out record separators
+sub STATE_GETDATA() {3} #have header, get data
+sub STATE_FLUSH() {4} #puts us back in wait state and tells us to kill the parsed_record
+sub STATE_TEXTRESPONSE() {5} #used for api output
+
+sub new {
+ my $class = shift;
+ my %args = @_;
+
+ my $strict = 0;
+ my $debug = 0;
+
+ if(defined($args{'debug'})) {
+ $debug = $args{'debug'};
+ }
+
+ if(defined($args{'strict'}) && $args{'strict'} == 1) {
+ $strict = $args{'strict'};
+ }
+
+ #our filter is line based, don't reinvent the wheel
+ my $line_filter = POE::Filter::Line->new();
+
+ my $self = bless [
+ "", #not used by me but the baseclass clone wants it here
+ $line_filter, #LINE_FILTER
+ STATE_WAITING, #PARSER_STATE
+ undef, #PARSER_STATE
+ {}, #PARSED_RECORD
+ 0, #length tracking (for Content-Length when needed)
+ $strict, #whether we should bail on a bad parse or try and save the session
+ $debug, #debug level
+ ], $class;
+
+ return $self;
+}
+
+
+sub get_one_start {
+ my ($self, $stream) = @_;
+ $self->[LINE_FILTER]->get_one_start($stream);
+}
+
+sub get_one {
+ my $self = shift;
+
+ while(1) {
+ #grab a line from the filter
+ my $line = $self->[LINE_FILTER]->get_one();
+
+ #quit if we can't get any lines
+ return [] unless @$line;
+
+ #get the actual line
+ $line = $line->[0];
+
+ if(($self->[PARSER_STATE] == STATE_WAITING) || ($self->[PARSER_STATE] == STATE_FLUSH)) {
+ #see if we need to wipe out the parsed_record info
+ if($self->[PARSER_STATE] == STATE_FLUSH) {
+ delete $self->[PARSED_RECORD];
+ $self->[CURRENT_LENGTH] = 0;
+
+ $self->[PARSER_STATE] = STATE_WAITING;
+ }
+
+ if($line =~ /Content-Length:\ (\d+)$/) {
+ #store the length
+ $self->[PARSED_RECORD]{'Content-Length'} = $1;
+
+ #see if we had a place to go from here (we should)
+ if(defined($self->[PARSER_STATENEXT])) {
+ $self->[PARSER_STATE] = $self->[PARSER_STATENEXT];
+ $self->[PARSER_STATENEXT] = undef;
+ }
+ } elsif($line =~ /Content-Type:\ (.*)$/) {
+ #store the type of request
+ $self->[PARSED_RECORD]{'Content-Type'} = $1;
+
+ if($1 eq "auth/request") {
+ $self->[PARSER_STATE] = STATE_CLEANUP;
+ $self->[PARSER_STATENEXT] = STATE_FLUSH;
+ return [ $self->[PARSED_RECORD] ];
+ } elsif ($1 eq "command/reply") { #do something with this later
+ $self->[PARSER_STATE] = STATE_GETDATA;
+ } elsif ($1 eq "text/event-plain") {
+ $self->[PARSER_STATE] = STATE_CLEANUP;
+ $self->[PARSER_STATENEXT] = STATE_GETDATA;
+ } elsif ($1 eq "api/response") {
+ $self->[PARSER_STATENEXT] = STATE_TEXTRESPONSE;
+ } elsif ($1 eq "log/data") {
+ $self->[PARSER_STATENEXT] = STATE_TEXTRESPONSE;
+ } else { #unexpected input
+ croak ref($self) . " unknown input [" . $self->[PARSER_STATE] . "] (" . $line . ")";
+ }
+ } else {
+ #already in wait state, if we are not in strict, keep going
+ if($self->[STRICT_PARSE]) {
+ croak ref($self) . " unknown input [STATE_WAITING] (" . $line . ")";
+ }
+ }
+ } elsif ($self->[PARSER_STATE] == STATE_CLEANUP) {
+ if($line eq "") {
+ if(defined($self->[PARSER_STATENEXT])) {
+ $self->[PARSER_STATE] = $self->[PARSER_STATENEXT];
+ $self->[PARSER_STATENEXT] = undef;
+ } else {
+ $self->[PARSER_STATE] = STATE_WAITING;
+ }
+ } else {
+ #see if we should bail
+ if($self->[STRICT_PARSE]) {
+ croak ref($self) . " unknown input [STATE_CLEANUP] (" . $line . ")";
+ } else {
+ #we are not supposed to bail so try and save our session...
+ #since we are think we should be cleaning up, flush it all away
+ $self->[PARSER_STATE] = STATE_FLUSH;
+
+ #parser fail should be considered critical, if any debug at all, print dump
+ if($self->[DEBUG_LEVEL]) {
+ print STDERR "Parse failed on ($line) in STATE_CLEANUP:\n";
+ print STDERR Dumper $self->[PARSED_RECORD];
+ }
+ }
+ }
+ } elsif ($self->[PARSER_STATE] == STATE_GETDATA) {
+ if($line =~ /^([^:]+):\ (.*)$/) {
+ $self->[PARSED_RECORD]{$1} = $2;
+ } elsif ($line eq "") { #end of event
+ $self->[PARSER_STATE] = STATE_FLUSH;
+
+ return [ $self->[PARSED_RECORD] ];
+ } else {
+ if($self->[STRICT_PARSE]) {
+ croak ref($self) . " unknown input [STATE_GETDATA] (" . $line . ")";
+ } else {
+ #flush and run
+ $self->[PARSER_STATE] = STATE_FLUSH;
+
+ #parser fail should be considered critical, if any debug at all, print dump
+ if($self->[DEBUG_LEVEL]) {
+ print STDERR "Parse failed on ($line) in STATE_GETDATA:\n";
+ print STDERR Dumper $self->[PARSED_RECORD];
+ }
+ }
+ }
+ } elsif ($self->[PARSER_STATE] == STATE_TEXTRESPONSE) {
+ if($self->[CURRENT_LENGTH] == -1) {
+ $self->[CURRENT_LENGTH] = 0;
+ next;
+ }
+
+ $self->[CURRENT_LENGTH] += (length($line) + 1);
+
+ if(($self->[CURRENT_LENGTH] - 1) == $self->[PARSED_RECORD]{'Content-Length'}) {
+ $self->[PARSER_STATE] = STATE_FLUSH;
+ $self->[PARSED_RECORD]{'__DATA__'} .= $line;
+
+ return [$self->[PARSED_RECORD]];
+ } else {
+ $self->[PARSED_RECORD]{'__DATA__'} .= $line . "\n";
+ }
+ }
+ }
+}
+
+sub put {
+ my ($self, $lines) = @_;
+
+ my @row;
+ foreach my $line (@$lines) {
+ push @row, $line . "\n\n";
+ }
+
+ return \@row;
+
+}
+
+sub get_pending {
+ my $self = shift;
+ return $self->[LINE_FILTER]->get_pending();
+}
+
+sub get {
+ my ($self, $stream) = @_;
+ my @return;
+
+ $self->get_one_start($stream);
+ while(1) {
+ my $next = $self->get_one();
+ last unless @$next;
+ push @return, @$next;
+ }
+
+ return \@return;
+}
+
+1;
+
+=head1 SEE ALSO
+
+FreeSWITCH - http://www.freeswitch.org/
+
+=head1 AUTHORS
+
+POE::Filter::FSSocket is written by Paul Tinsley. You can reach him by e-mail
+at pdt(a)jackhammer.org.
+
+=head1 COPYRIGHT
+
+Copyright 2006, Paul Tinsley. All rights are reserved.
+
+POE::Filter::FSSocket is free software; it is currently licensed under the MPL
+license version 1.1.
+
+=cut
Added: freeswitch/trunk/scripts/POE-Filter-FSSocket/t/01_basic.t
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/POE-Filter-FSSocket/t/01_basic.t Fri Oct 20 02:20:39 2006
@@ -0,0 +1,10 @@
+#!/usr/bin/env perl
+
+use warnings;
+use strict;
+
+use Test::More tests => 1;
+
+use_ok("POE::Filter::FSSocket");
+
+exit;
Added: freeswitch/trunk/scripts/socket/fsconsole.pl
==============================================================================
--- (empty file)
+++ freeswitch/trunk/scripts/socket/fsconsole.pl Fri Oct 20 02:20:39 2006
@@ -0,0 +1,361 @@
+#!/usr/bin/perl
+use strict;
+use warnings;
+
+sub POE::Kernel::ASSERT_DEFAULT () { 1 };
+sub Term::Visual::DEBUG () { 1 }
+sub Term::Visual::DEBUG_FILE () { 'test.log' }
+use IO::Socket;
+use POE qw/Filter::FSSocket Component::Client::TCP/;
+use Data::Dumper;
+use Term::Visual;
+
+
+local *D;
+if (Term::Visual::DEBUG) {
+ *D = *Term::Visual::ERRS;
+}
+
+#local *ERROR = *STDERR;
+
+
+$SIG{__DIE__} = sub {
+ if (Term::Visual::DEBUG) {
+ print Term::Visual::ERRS "Died: @_\n";
+ }
+};
+
+###############################################################################
+## BEGIN Globals ##############################################################
+###############################################################################
+our $server_address = "127.0.0.1";
+our $server_port = "8021";
+our $server_secret = "ClueCon";
+
+#this is where you can customize the color scheme
+our %Pallet = (
+ 'warn_bullet' => 'bold yellow',
+ 'err_bullet' => 'bold red',
+ 'out_bullet' => 'bold green',
+ 'access' => 'bright red on blue',
+ 'current' => 'bright yellow on blue',
+);
+
+our $terminal;
+my %sockets;
+my %windows;
+my %unread_count;
+my %commands = (
+ 'window' => 1,
+ 'w' => 1,
+ 'win' => 1,
+);
+###############################################################################
+## END Globals ##############################################################
+###############################################################################
+
+#setup our session
+POE::Session->create(
+ 'inline_states' => {
+ '_start' => \&handle_start, #session start
+ '_stop' => \&handle_stop, #session stop
+ 'curses_input' => \&handle_curses_input, #input from the keyboard
+ 'update_time' => \&handle_update_time, #update the status line clock
+ 'quit' => \&handle_quit, #handler to do any cleanup
+ 'server_input' => \&handle_server_input,
+ '_default' => \&handle_default,
+ },
+ 'heap' => {
+ 'terminal' => undef,
+ 'freeswitch' => undef,
+ },
+);
+
+#start the kernel a chugging along
+$poe_kernel->run;
+
+###############################################################################
+## BEGIN Handlers #############################################################
+###############################################################################
+#handles any startup functions for our session
+sub handle_default {
+}
+
+sub handle_start {
+ my ($kernel, $session, $heap) = @_[KERNEL, SESSION, HEAP];
+
+ #setup our terminal
+ $heap->{'terminal'} = Term::Visual->new(
+ 'Alias' => 'terminal', #poe alias for this
+ 'History_Size' => 300, #number of things to keep in history
+ 'Common_Input' => 1, #all windows share input and history
+ 'Tab_Complete' => \&tab_complete,
+ );
+
+ $terminal = $heap->{'terminal'};
+
+ #setup the color palette
+ $terminal->set_palette(%Pallet);
+
+ #create a base window
+ my $window_id = $terminal->create_window(
+ 'Window_Name' => 'console',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Console',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'console'} = $window_id;
+
+ $window_id = $terminal->create_window(
+ 'Window_Name' => 'log',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Logs',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'log'} = $window_id;
+
+ $window_id = $terminal->create_window(
+ 'Window_Name' => 'event',
+ 'Buffer_Size' => 3000,
+ 'Title' => 'FreeSWITCH Event',
+ 'Status' => {
+ '0' => {
+ 'format' => '%s',
+ 'fields' => ['time'],
+ },
+ '1' => {
+ 'format' => '%s',
+ 'fields' => ['window_status'],
+ },
+ },
+ );
+
+ $windows{'event'} = $window_id;
+
+ #tell the terminal what to call when there is input from the keyboard
+ $kernel->post('terminal' => 'send_me_input' => 'curses_input');
+
+ $terminal->change_window(0);
+ $kernel->delay_set('update_time' => 1);
+ $terminal->set_status_field(0, 'time' => scalar(localtime));
+ new_message('destination_window' => 0, 'message' => "
+Welcome to the FreeSWITCH POE Curses Console!
+ The console is split into three windows:
+ - 'console' for api response messages
+ - 'log' for freeswitch log output (simply send the log level you want
+ to start seeing events eg: 'log all')
+ - 'event' for freeswitch event output (must subscribe in plain format
+ eg: 'event plain all')
+
+To switch between windows type 'w <windowname' so 'w log' for example.
+
+Coming soon:
+ - Tab completion
+ - command history
+ - window status in the bar (messages added since last view, etc...)
+
+Send any bug reports or comments to jackhammer\(a)gmail.com
+
+Thanks,
+Paul\n");
+
+ $terminal->set_status_field($terminal->current_window, 'window_status' => format_window_status());
+
+ #connect to freeswitch
+ $heap->{'freeswitch'} = POE::Component::Client::TCP->new(
+ 'RemoteAddress' => $server_address,
+ 'RemotePort' => $server_port,
+ 'ServerInput' => \&handle_server_input,
+ 'Connected' => \&handle_fs_connected,
+ 'ServerError' => \&handle_server_error,
+ 'Disconnected' => \&handle_server_disconnect,
+ 'Domain' => AF_INET,
+ 'Filter' => POE::Filter::FSSocket->new(),
+ );
+
+}
+
+#called when users enter commands in a window
+sub handle_curses_input {
+ my ($kernel, $heap, $input, $context) = @_[KERNEL, HEAP, ARG0, ARG1];
+
+ #get the id of the window that is responsible for the input
+ my $window = $heap->{'terminal'}->current_window;
+
+ open(ERROR, ">>error.log");
+
+ if($input eq "quit") {
+ $kernel->yield('quit');
+ } elsif ($input =~ /^w\ (.*)$/) {
+ #get the id of the requested window
+ eval {
+ my $window_id = $windows{$1};
+
+ #see if it's real
+ if(defined($window_id)) {
+ $unread_count{$window_id} = 0;
+ $terminal->change_window($window_id);
+ $terminal->set_status_field($window_id, 'window_status' => &format_window_status());
+ }
+ };
+ if($@) {
+ print ERROR "put error: $@\n";
+ }
+ } else {
+ #see if we got connected at some point
+ if(defined($sockets{'localhost'})) {
+ #send the command
+ $sockets{'localhost'}->put($input);
+ }
+ }
+}
+
+sub handle_fs_connected {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+ eval {
+ $sockets{'localhost'} = $heap->{'server'};
+ }
+}
+
+#this is responsible for doing any cleanup and returning the terminal to the previous
+#state before we mucked with it
+sub handle_quit {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+
+ #tell curses to clean up it's crap
+ $kernel->post('terminal' => 'shutdown');
+
+ #there is probably a more elegant way, but this works for now
+ exit;
+}
+
+#data from freeswitch
+sub handle_server_input {
+ my ($kernel,$heap,$input) = @_[KERNEL,HEAP,ARG0];
+
+ eval {
+ #terminal HATES null
+ if(defined($input->{'__DATA__'})) {
+ $input->{'__DATA__'} =~ s/[\x00]//g;
+ }
+
+ #handle the login
+ if($input->{'Content-Type'} eq "auth/request") {
+ $heap->{'server'}->put("auth $server_secret");
+ } elsif ($input->{'Content-Type'} eq "api/response") {
+ new_message('destination_window' => 0, 'message' => 'Response: ');
+ new_message('destination_window' => 0, 'message' => $input->{'__DATA__'});
+ } elsif ($input->{'Content-Type'} eq "log/data") {
+ new_message('destination_window' => 1, 'message' => $input->{'__DATA__'});
+ } elsif ($input->{'Content-Type'} eq "text/event-plain") {
+ new_message('destination_window' => 2, 'message' => Dumper $input);
+ }
+ };
+
+ if($@) {
+ open(ERROR, ">>error.log");
+ print ERROR "died: $@\n";
+ print ERROR Dumper $heap;
+ close(ERROR);
+ }
+}
+
+sub handle_server_error {
+}
+
+sub handle_server_disconnect {
+}
+
+sub tab_complete {
+ my $left = shift;
+
+ my @return;
+
+ if(defined($commands{$left})) {
+ return [$left . " "];
+ #} elsif () {
+ }
+
+}
+
+sub handle_update_time {
+ my ($kernel, $heap) = @_[KERNEL, HEAP];
+ $terminal->set_status_field($terminal->current_window, 'time' => scalar(localtime));
+ $kernel->delay_set('update_time' => 1);
+}
+###############################################################################
+## END Handlers #############################################################
+###############################################################################
+
+sub new_message {
+ my %args = @_;
+
+ my $message = $args{'message'};
+ my $destination_window = $args{'destination_window'};
+
+ my $status_field;
+
+ #see if we are on the window being updated
+ if($terminal->current_window != $destination_window) {
+ #increment the unread count for the window
+ #FIXME, should we count messages or lines?
+ $unread_count{$destination_window}++;
+
+
+ #update the status bar
+ eval {
+ $terminal->set_status_field($terminal->current_window, 'window_status' => &format_window_status());
+ };
+
+ if($@) {
+ print $@;
+ }
+ }
+
+
+ #deliver the message
+ $terminal->print($destination_window, $message);
+}
+
+sub format_window_status {
+ my $status_field;
+
+ #put all the windows in the bar with their current unread count
+ foreach my $window (sort {$windows{$a} <=> $windows{$b}} keys %windows) {
+ #see if we are printing the current window
+ if($terminal->current_window == $windows{$window}) {
+ $status_field .= "[\0(current)$window\0(st_frames)";
+ } else {
+ $status_field .= "[$window";
+ }
+
+ if($unread_count{$windows{$window}}) {
+ $status_field .= " (" . $unread_count{$windows{$window}} . ")";
+ }
+
+ $status_field .= "] ";
+ }
+
+ return $status_field;
+}
1
0
[commit] r3115 - in freeswitch/trunk: conf libs/libdingaling/src src/mod/dialplans/mod_dialplan_xml src/mod/endpoints/mod_dingaling src/mod/endpoints/mod_sofia
by Freeswitch SVN 20 Oct '06
by Freeswitch SVN 20 Oct '06
20 Oct '06
Author: anthm
Date: Fri Oct 20 02:17:00 2006
New Revision: 3115
Modified:
freeswitch/trunk/conf/freeswitch.xml
freeswitch/trunk/libs/libdingaling/src/libdingaling.c
freeswitch/trunk/libs/libdingaling/src/libdingaling.h
freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
Presence and Chat Gateway Code
This is some brand new stuff to gateway chat/presence/audio from one protocol to another
So far it only works between google/jingle and SIP
All I had to test the SIP end was X-Lite and Eyebeam and GoogleTalk on the jingle end.
With this setup registered X-Lite's can chat with each other and call each other
as well as X-Lite to GoogleTalk and GoogleTalk to X-Lite audio calls.
Chat May also be done between X-Lite and jabber
You'll also need a jabber server configured for component login so you can interface.
We have only tested with jabberd2 so far.
Configure DNS so srv records for jabber for your subdomain (fs.mydomain.com in the example)
so the jabber records are pointed at your jabber server.
RELEVANT CONFIGS
<!-- Brian has no jingle support so send calls to him over to his iax url -->
<extension name="bkw">
<condition field="destination_number" expression="^jingle\+brian(a)agents.cylynx.com$">
<action application="bridge" data="iax/guest(a)brianwest.homeunix.org/9184290404"/>
</condition>
</extension>
<!-- Assumption is made here that both sip and jingle have the same profile/domain name as documented below -->
<extension name="jingle2sip">
<condition field="source" expression="mod_dingaling"/>
<condition field="destination_number" expression="^sip\+([^\@]+)\@(.*)$">
<action application="bridge" data="sofia/$2/$1%$2"/>
</condition>
</extension>
<extension name="sip2jingle">
<condition field="source" expression="mod_sofia"/>
<condition field="destination_number" expression="^jingle\+([^\@]+)\@(.*)$">
<action application="bridge" data="dingaling/sip+${sip_fromuser}@${sip_fromhost}/$1@$2"/>
</condition>
</extension>
<configuration name="sofia.conf" description="sofia Endpoint">
<global_settings>
<param name="log-level" value="0"/>
</global_settings>
<profiles>
<profile name="fs.mydomain.com">
<registrations/>
<settings>
<param name="debug" value="1"/>
<param name="rfc2833-pt" value="101"/>
<param name="sip-port" value="5060"/>
<param name="dialplan" value="XML"/>
<param name="dtmf-duration" value="100"/>
<param name="codec-prefs" value="PCMU"/>
<param name="codec-ms" value="20"/>
<param name="accept-blind-reg" value="true"/>
<param name="manage-presence" value="true"/>
<!--<param name="full-id-in-dialplan" value="true"/>-->
<!--<param name="auth-calls" value="true"/>-->
<!--<param name="auth-all-packets" value="true"/>-->
<param name="use-rtp-timer" value="true"/>
<param name="rtp-timer-name" value="soft"/>
<param name="rtp-ip" value="100.200.100.200"/>
<param name="sip-ip" value="fs.mydomain.com"/>
</settings>
</profile>
</profiles>
</configuration>
<configuration name="dingaling.conf" description="XMPP Jingle Endpoint">
<settings>
<param name="debug" value="0"/>
<param name="codec-prefs" value="PCMU"/>
</settings>
<profile type="component">
<param name="name" value="fs.mydomain.com"/>
<param name="password" value="secret"/>
<param name="dialplan" value="XML"/>
<param name="rtp-ip" value="208.64.200.42"/>
<param name="server" value="jabber.freeswitch.org:5347"/>
<!-- disable to trade async for more calls -->
<param name="use-rtp-timer" value="true"/>
<param name="exten" value="_auto_"/>
<!--<param name="vad" value="both"/>-->
</profile>
</configuration>
Modified: freeswitch/trunk/conf/freeswitch.xml
==============================================================================
--- freeswitch/trunk/conf/freeswitch.xml (original)
+++ freeswitch/trunk/conf/freeswitch.xml Fri Oct 20 02:17:00 2006
@@ -113,8 +113,8 @@
</configuration>
<configuration name="sofia.conf" description="sofia Endpoint">
- <profiles>
- <profile name="test">
+ <profile>
+ <profile name="mydomain1.com">
<registrations>
<!-- <registration name="asterlink">
<param name="register-scheme" value="Digest"/>
@@ -138,7 +138,7 @@
<param name="use-rtp-timer" value="true"/>
<param name="rtp-timer-name" value="soft"/>
<param name="rtp-ip" value="192.168.1.20"/>
- <param name="sip-ip" value="192.168.1.20"/>
+ <param name="sip-ip" value="mydomain1.com"/>
<!-- this lets anything register -->
<!-- comment the next line and uncomment one or both of the other 2 lines for call authentication -->
@@ -268,10 +268,12 @@
<param name="debug" value="0"/>
<param name="codec-prefs" value="PCMU"/>
</settings>
- <!-- *NOTE* your resource (after the /) MUST contain the string "talk" (upper or lower case is ok) -->
- <!-- *NOTE* as of May 2 2006 you must set"auto-login" to"true" if you want to be able to auto-login on startup"/> -->
- <interface>
- <param name="name" value="jingle"/>
+
+ <!-- *NOTE* change <x-profile></x-profile> to <profile></profile> to enable -->
+
+ <!-- Client Profile (Original mode) -->
+ <x-profile type="client">
+ <param name="name" value="mydomain.com"/>
<param name="login" value="myjid(a)myserver.com/talk"/>
<param name="password" value="mypass"/>
<param name="dialplan" value="XML"/>
@@ -296,7 +298,23 @@
<!-- <param name="vad" value="in"/> -->
<!-- <param name="vad" value="out"/> -->
<param name="vad" value="both"/>
- </interface>
+ </x-profile>
+
+ <!-- Component (Server to Server Login) -->
+ <x-profile type="component">
+ <!-- All traffic for *(a)sub.mydomain.com will come to you -->
+ <param name="name" value="sub.mydomain.com"/>
+ <param name="password" value="secret"/>
+ <param name="dialplan" value="XML"/>
+ <param name="rtp-ip" value="208.64.200.42"/>
+ <param name="server" value="jabber.server.org:5347"/>
+ <!-- disable to trade async for more calls -->
+ <param name="use-rtp-timer" value="true"/>
+ <!-- "_auto_" means the extension will be automaticly set to the called jid -->
+ <param name="exten" value="_auto_"/>
+ <!--<param name="vad" value="both"/>-->
+ </x-profile>
+
</configuration>
<configuration name="xml_rpc.conf" description="XML RPC">
Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.c (original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.c Fri Oct 20 02:17:00 2006
@@ -712,7 +712,7 @@
if (!type || (type && strcasecmp(type, "probe"))) {
if (handle->session_callback) {
- handle->session_callback(handle, NULL, signal, to, from, status ? status : "n/a", show ? show : "n/a");
+ handle->session_callback(handle, NULL, signal, to, id, status ? status : "n/a", show ? show : "n/a");
}
}
@@ -720,7 +720,7 @@
return IKS_FILTER_EAT;
}
-static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
+static void do_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message)
{
iks *pres;
char buf[512];
@@ -743,21 +743,28 @@
iks_insert_attrib(pres, "type", type);
}
+ if (rpid) {
+ if ((tag = iks_insert (pres, "show"))) {
+ iks_insert_cdata(tag, rpid, 0);
+ }
+ }
-
- if (message) {
+ if (message) {
if ((tag = iks_insert (pres, "status"))) {
- iks_insert_cdata(tag, message ? message : "", 0);
- if ((tag = iks_insert(pres, "c"))) {
- iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
- iks_insert_attrib(tag, "ver", "1.0.0.1");
- iks_insert_attrib(tag, "ext", "sidebar voice-v1");
- iks_insert_attrib(tag, "client", "libdingaling2");
- iks_insert_attrib(tag, "xmlns", "http://jabber.org/protocol/caps");
- }
+ iks_insert_cdata(tag, message, 0);
}
}
-
+
+ if (message || rpid) {
+ if ((tag = iks_insert(pres, "c"))) {
+ iks_insert_attrib(tag, "node", "http://www.freeswitch.org/xmpp/client/caps");
+ iks_insert_attrib(tag, "ver", "1.0.0.1");
+ iks_insert_attrib(tag, "ext", "sidebar voice-v1");
+ iks_insert_attrib(tag, "client", "libdingaling");
+ iks_insert_attrib(tag, "xmlns", "http://jabber.org/protocol/caps");
+ }
+ }
+
apr_queue_push(handle->queue, pres);
}
}
@@ -1559,9 +1566,9 @@
return handle->private_info;
}
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message)
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message)
{
- do_presence(handle, from, to, type, message);
+ do_presence(handle, from, to, type, rpid, message);
}
void ldl_handle_send_msg(ldl_handle_t *handle, char *from, char *to, char *subject, char *body)
Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.h
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.h (original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.h Fri Oct 20 02:17:00 2006
@@ -369,9 +369,10 @@
\param from the from address
\param to the to address
\param type the type of presence
+ \param rpid data for the icon
\param message a status message
*/
-void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *message);
+void ldl_handle_send_presence(ldl_handle_t *handle, char *from, char *to, char *type, char *rpid, char *message);
/*!
\brief Send a message
Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c (original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c Fri Oct 20 02:17:00 2006
@@ -94,6 +94,11 @@
for (x = 0; x < (len-1) && x < strlen(data);) {
if (data[x] == '$') {
x++;
+
+ if (!(data[x] > 47 && data[x] < 58)) {
+ substituted[y++] = data[x-1];
+ continue;
+ }
while (data[x] > 47 && data[x] < 58) {
index[z++] = data[x];
Modified: freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_dingaling/mod_dingaling.c Fri Oct 20 02:17:00 2006
@@ -47,7 +47,9 @@
static char sub_sql[] =
"CREATE TABLE subscriptions (\n"
" sub_from VARCHAR(255),\n"
-" sub_to VARCHAR(255)\n"
+" sub_to VARCHAR(255),\n"
+" show VARCHAR(255),\n"
+" status VARCHAR(255)\n"
");\n";
@@ -186,7 +188,39 @@
static ldl_status handle_response(ldl_handle_t *handle, char *id);
static switch_status_t load_config(void);
+static char *translate_rpid(char *in, char *ext)
+{
+ char *r = NULL;
+ if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
+ in = NULL;
+ }
+
+ if (!in) {
+ in = ext;
+ }
+
+ if (!in) {
+ return NULL;
+ }
+
+ if (!strcasecmp(in, "busy")) {
+ r = "dnd";
+ }
+
+ if (!strcasecmp(in, "unavailable")) {
+ r = "dnd";
+ }
+
+ if (ext && !strcasecmp(ext, "idle")) {
+ r = "away";
+ } else if (ext && !strcasecmp(ext, "away")) {
+ r = "away";
+ }
+
+ return r;
+}
+
static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
{
struct mdl_profile *profile = (struct mdl_profile *) pArg;
@@ -194,17 +228,18 @@
char *sub_from = argv[0];
char *sub_to = argv[1];
char *type = argv[2];
- char *show = argv[3];
+ char *rpid = argv[3];
+ char *status = argv[4];
if (switch_strlen_zero(type)) {
type = NULL;
} else if (!strcasecmp(type, "unavailable")) {
- show = NULL;
+ status = NULL;
}
+ rpid = translate_rpid(rpid, status);
+
+ ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, rpid, status);
-
- ldl_handle_send_presence(profile->handle, sub_to, sub_from, type, show);
-
return 0;
}
@@ -215,9 +250,17 @@
char *sub_from = argv[0];
char *sub_to = argv[1];
char *show = argv[2];
+ char *status = argv[3];
+ if (!strcasecmp(status, "n/a")) {
+ if (!strcasecmp(show, "dnd")) {
+ status = "Busy";
+ } else if (!strcasecmp(show, "away")) {
+ status = "Idle";
+ }
+ }
- ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show);
+ ldl_handle_send_presence(profile->handle, sub_to, sub_from, NULL, show, status);
return 0;
}
@@ -229,22 +272,17 @@
void *val;
char *from = switch_event_get_header(event, "from");
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
- char *type = NULL;
+ char *rpid = switch_event_get_header(event, "rpid");
+ char *type = switch_event_get_header(event, "event_subtype");
char *sql;
switch_core_db_t *db;
char *p;
if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
+ status = NULL;
}
-
-
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
if (!status) {
@@ -259,12 +297,12 @@
}
-
if ((p = strchr(from, '/'))) {
*p = '\0';
}
- sql = switch_mprintf("select *,'%q','%q' from subscriptions where sub_to='%q'", type ? type : "", status ? status : "unavailable", from);
+ sql = switch_mprintf("select sub_from, sub_to,'%q','%q','%q' from subscriptions where sub_to='%q'",
+ type ? type : "", rpid, status ? status : "unavailable", from);
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
char *errmsg;
switch_hash_this(hi, NULL, NULL, &val);
@@ -326,7 +364,7 @@
static void roster_event_handler(switch_event_t *event)
{
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
+ char *from= switch_event_get_header(event, "from");
char *event_type = switch_event_get_header(event, "event_type");
struct mdl_profile *profile = NULL;
switch_hash_index_t *hi;
@@ -334,19 +372,19 @@
char *sql;
switch_core_db_t *db;
-
if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
+ status = NULL;
}
if (switch_strlen_zero(event_type)) {
event_type="presence";
}
- sql = switch_mprintf("select *,'%q' from subscriptions", show ? show : "unavilable");
+ if (from) {
+ sql = switch_mprintf("select *,'%q' from subscriptions where sub_from='%q'", status ? status : "", from);
+ } else {
+ sql = switch_mprintf("select *,'%q' from subscriptions", status ? status : "");
+ }
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
char *errmsg;
@@ -457,7 +495,13 @@
{
ldl_handle_t *handle = obj;
struct mdl_profile *profile = NULL;
+ switch_event_t *event;
+ if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
+ switch_event_fire(&event);
+ }
+
profile = ldl_handle_get_private(handle);
globals.handles++;
switch_set_flag(profile, TFLAG_IO);
@@ -1307,7 +1351,7 @@
snprintf(ubuf, sizeof(ubuf), "%s@%s/talk", u, profile_name);
user = ubuf;
} else {
- user = mdl_profile->login;
+ user = (char *) modname;
}
if ((mdl_profile = switch_core_hash_find(globals.profile_hash, profile_name))) {
@@ -1554,25 +1598,6 @@
if (switch_true(val)) {
profile->user_flags |= LDL_FLAG_TLS;
}
- } else if (!strcasecmp(var, "component")) {
- if (switch_true(val)) {
- char dbname[256];
- switch_core_db_t *db;
-
- profile->user_flags |= LDL_FLAG_COMPONENT;
- switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
- snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
- profile->dbname = switch_core_strdup(module_pool, dbname);
-
- if ((db = switch_core_db_open_file(profile->dbname))) {
- switch_core_db_test_reactive(db, "select * from subscriptions", sub_sql);
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
- return;
- }
- switch_core_db_close(db);
-
- }
} else if (!strcasecmp(var, "sasl")) {
if (!strcasecmp(val, "plain")) {
profile->user_flags |= LDL_FLAG_SASL_PLAIN;
@@ -1669,6 +1694,7 @@
}
}
+
if (profile && init_profile(profile, 1) == SWITCH_STATUS_SUCCESS) {
stream->write_function(stream, "OK\n");
} else {
@@ -1715,7 +1741,14 @@
}
}
- for (xmlint = switch_xml_child(cfg, "interface"); xmlint; xmlint = xmlint->next) {
+ if (!(xmlint = switch_xml_child(cfg, "profile"))) {
+ if ((xmlint = switch_xml_child(cfg, "interface"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "!!!!!!! DEPRICATION WARNING 'interface' is now 'profile' !!!!!!!\n");
+ }
+ }
+
+ for (; xmlint; xmlint = xmlint->next) {
+ char *type = (char *) switch_xml_attr_soft(xmlint, "type");
for (param = switch_xml_child(xmlint, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
@@ -1732,6 +1765,31 @@
set_profile_val(profile, var, val);
}
+
+ if (type && !strcasecmp(type, "component")) {
+ char dbname[256];
+ switch_core_db_t *db;
+
+ if (!profile->login && profile->name) {
+ profile->login = switch_core_strdup(module_pool, profile->name);
+ }
+
+ switch_set_flag(profile, TFLAG_AUTO);
+ profile->message = "";
+ profile->user_flags |= LDL_FLAG_COMPONENT;
+ switch_mutex_init(&profile->mutex, SWITCH_MUTEX_NESTED, module_pool);
+ snprintf(dbname, sizeof(dbname), "dingaling_%s", profile->name);
+ profile->dbname = switch_core_strdup(module_pool, dbname);
+
+ if ((db = switch_core_db_open_file(profile->dbname))) {
+ switch_core_db_test_reactive(db, "select * from subscriptions", sub_sql);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open SQL Database!\n");
+ continue;
+ }
+ switch_core_db_close(db);
+ }
+
if (profile) {
init_profile(profile, switch_test_flag(profile, TFLAG_AUTO) ? 1 : 0);
profile = NULL;
@@ -1815,7 +1873,7 @@
case LDL_SIGNAL_SUBSCRIBE:
if ((profile->user_flags & LDL_FLAG_COMPONENT)) {
- if ((sql = switch_mprintf("insert into subscriptions values('%q','%q')", from, to))) {
+ if ((sql = switch_mprintf("insert into subscriptions values('%q','%q','%q','%q')", from, to, msg, subject))) {
execute_sql(profile->dbname, sql, profile->mutex);
switch_core_db_free(sql);
}
@@ -1829,17 +1887,30 @@
}
break;
case LDL_SIGNAL_PRESENCE_IN:
+
+ if ((sql = switch_mprintf("update subscriptions set show='%q', status='%q' where sub_from='%q'", msg, subject, from))) {
+ execute_sql(profile->dbname, sql, profile->mutex);
+ switch_core_db_free(sql);
+ }
+
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", msg);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", subject);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", msg);
switch_event_fire(&event);
}
break;
+
case LDL_SIGNAL_PRESENCE_OUT:
+
+ if ((sql = switch_mprintf("update subscriptions set show='%q', status='%q' where sub_from='%q'", msg, subject, from))) {
+ execute_sql(profile->dbname, sql, profile->mutex);
+ switch_core_db_free(sql);
+ }
+
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", MDL_CHAT_NAME);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->login);
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Fri Oct 20 02:17:00 2006
@@ -43,9 +43,6 @@
struct outbound_reg;
typedef struct outbound_reg outbound_reg_t;
-struct sip_presence;
-typedef struct sip_presence sip_presence_t;
-
struct sofia_profile;
typedef struct sofia_profile sofia_profile_t;
#define NUA_MAGIC_T sofia_profile_t
@@ -53,7 +50,6 @@
struct sofia_private {
switch_core_session_t *session;
outbound_reg_t *oreg;
- sip_presence_t *presence;
};
typedef struct sofia_private sofia_private_t;
@@ -86,6 +82,7 @@
" host VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
" status VARCHAR(255),\n"
+" rpid VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
@@ -211,13 +208,6 @@
};
-struct sip_presence {
- sofia_private_t sofia_private;
- nua_handle_t *nh;
- sofia_profile_t *profile;
-};
-
-
struct sofia_profile {
int debug;
char *name;
@@ -251,7 +241,6 @@
switch_mutex_t *ireg_mutex;
switch_mutex_t *oreg_mutex;
outbound_reg_t *registrations;
- sip_presence_t *presence;
su_home_t *home;
switch_hash_t *profile_hash;
switch_hash_t *chat_hash;
@@ -2673,17 +2662,15 @@
switch_event_t *s_event;
char *from_user = (char *) from->a_url->url_user;
char *from_host = (char *) from->a_url->url_host;
- char contact_str[1025] = "";
+ char contact_str[1024] = "";
char buf[512];
char *passwd = NULL;
uint8_t stale = 0, ret = 0, forbidden = 0;
auth_res_t auth_res;
long exptime = 60;
switch_event_t *event;
+ char *rpid = "unknown";
-
-
-
if (sip->sip_contact) {
char *port = (char *) contact->m_url->url_port;
if (!port) {
@@ -2824,76 +2811,84 @@
}
reg:
- if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Registered', %ld)",
- from_user,
- from_host,
- contact_str,
- (long) time(NULL) + (long)exptime);
+ if (exptime) {
+ if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Registered', '%q', %ld)",
+ from_user,
+ from_host,
+ contact_str,
+ rpid,
+ (long) time(NULL) + (long)exptime);
- } else {
- sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld where user='%q' and host='%q'",
- contact_str,
- (long) time(NULL) + (long)exptime,
- from_user,
- from_host);
+ } else {
+ sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld, rpid='%q' where user='%q' and host='%q'",
+ contact_str,
+ (long) time(NULL) + (long)exptime,
+ rpid,
+ from_user,
+ from_host);
- }
+ }
- if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", contact_str);
- switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
- switch_event_fire(&s_event);
- }
+ if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact", "%s", contact_str);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
+ switch_event_fire(&s_event);
+ }
- if (sql) {
- execute_sql(profile->dbname, sql, profile->ireg_mutex);
- switch_safe_free(sql);
- sql = NULL;
- }
+ if (sql) {
+ execute_sql(profile->dbname, sql, profile->ireg_mutex);
+ switch_safe_free(sql);
+ sql = NULL;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register from [%s@%s] contact [%s] expires %ld\n",
- from_user,
- from_host,
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register:\nFrom: [%s@%s]\nContact: [%s]\nExpires: [%ld]\n",
+ from_user,
+ from_host,
contact_str,
(long)exptime
);
-
- if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
- switch_event_fire(&event);
- }
-
- if (exptime) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "Registered");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "Registered");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
} else {
+ if ((sql = switch_mprintf("delete from sip_subscriptions where user='%q' and host='%q'", from_user, from_host))) {
+ execute_sql(profile->dbname, sql, profile->ireg_mutex);
+ switch_safe_free(sql);
+ sql = NULL;
+ }
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "unavailable");
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "unavailable");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
switch_event_fire(&event);
}
}
+
+ if (switch_event_create(&event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
+ switch_event_fire(&event);
+ }
+
if (regtype == REG_REGISTER) {
nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact),
NUTAG_WITH_THIS(nua),
@@ -2920,9 +2915,9 @@
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", status);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", status);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", status);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_subtype", "probe");
switch_event_fire(&event);
}
@@ -2935,30 +2930,31 @@
char *pl;
char *id, *note;
uint32_t in = atoi(argv[0]);
- char *msg = argv[1];
- char *proto = argv[2];
- char *user = argv[3];
- char *host = argv[4];
- char *sub_to_user = argv[5];
- char *sub_to_host = argv[6];
- char *event = argv[7];
- char *contact = argv[8];
- char *callid = argv[9];
- char *full_from = argv[10];
- char *full_via = argv[11];
+ char *status = argv[1];
+ char *rpid = argv[2];
+ char *proto = argv[3];
+ char *user = argv[4];
+ char *host = argv[5];
+ char *sub_to_user = argv[6];
+ char *sub_to_host = argv[7];
+ char *event = argv[8];
+ char *contact = argv[9];
+ char *callid = argv[10];
+ char *full_from = argv[11];
+ char *full_via = argv[12];
nua_handle_t *nh;
- char *doing;
char *to;
char *open;
+ if (!rpid) {
+ rpid = "unknown";
+ }
if (in) {
- note = switch_mprintf("<dm:note>%s</dm:note>", msg);
- doing="available";
+ note = switch_mprintf("<dm:note>%s</dm:note>", status);
open = "open";
} else {
note = NULL;
- doing="unavailable";
open = "closed";
}
@@ -2984,9 +2980,8 @@
"<dm:person id='p06360c4a'>\r\n"
"<rpid:activities>\r\n"
"<rpid:%s/>\r\n"
- "<rpid:unknown/>\r\n"
"</rpid:activities>%s</dm:person>\r\n"
- "</presence>", id, open, doing, note);
+ "</presence>", id, open, rpid, note);
nh = nua_handle(profile->nua, NULL, TAG_END());
@@ -3022,7 +3017,7 @@
tagi_t tags[])
{
if (sip) {
- long exp;
+ long exp, exp_raw;
sip_to_t const *to = sip->sip_to;
sip_from_t const *from = sip->sip_from;
sip_contact_t const *contact = sip->sip_contact;
@@ -3040,8 +3035,8 @@
char *full_via = NULL;
switch_core_db_t *db;
char *errmsg;
+ char *sstr;
-
if (from) {
from_user = (char *) from->a_url->url_user;
from_host = (char *) from->a_url->url_host;
@@ -3094,10 +3089,10 @@
full_from = sip_header_as_string(profile->home, (void *)sip->sip_from);
full_via = sip_header_as_string(profile->home, (void *)sip->sip_via);
+ exp_raw = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
+ exp = (long) time(NULL) + exp_raw;
+
- exp = (long) time(NULL) + (sip->sip_expires ? sip->sip_expires->ex_delta : 60);
-
-
if ((sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and user='%q' and host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q';\n"
"insert into sip_subscriptions values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld)",
@@ -3123,27 +3118,29 @@
switch_safe_free(sql);
}
-
+ sstr = switch_mprintf("active;expires=%ld", exp_raw);
+
nua_respond(nh, SIP_202_ACCEPTED,
- SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=3600"),
+ SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
SIPTAG_FROM(sip->sip_to),
SIPTAG_TO(sip->sip_from),
SIPTAG_CONTACT_STR(to_str),
TAG_END());
-
+ switch_safe_free(sstr);
+
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
goto end;
}
- if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", to_user, to_host, to_user, to_host))) {
+ if ((sql = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'",
+ to_user, to_host, to_user, to_host))) {
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_core_db_close(db);
switch_safe_free(sql);
}
-
+ switch_core_db_close(db);
end:
if (event) {
@@ -3449,6 +3446,7 @@
sip_from_t const *from = sip->sip_from;
char *from_user = NULL;
char *from_host = NULL;
+ char *rpid = "unknown";
sip_payload_t *payload = sip->sip_payload;
char *event_type;
@@ -3458,7 +3456,7 @@
}
if (payload) {
- switch_xml_t xml, note, person, tuple, status, basic;
+ switch_xml_t xml, note, person, tuple, status, basic, act;
switch_event_t *event;
uint8_t in = 0;
char *sql;
@@ -3474,6 +3472,14 @@
note_txt = note->txt;
}
+ if (person && (act = switch_xml_child(person, "rpid:activities"))) {
+ if ((rpid = strchr(act->child->name, ':'))) {
+ rpid++;
+ } else {
+ rpid = act->child->name;
+ }
+ }
+
if (!strcasecmp(status_txt, "open")) {
if (switch_strlen_zero(note_txt)) {
note_txt = "Available";
@@ -3485,7 +3491,8 @@
}
}
- if ((sql = switch_mprintf("update sip_registrations set status='%q' where user='%q' and host='%q'", note_txt, from_user, from_host))) {
+ if ((sql = switch_mprintf("update sip_registrations set status='%q',rpid='%q' where user='%q' and host='%q'",
+ note_txt, rpid, from_user, from_host))) {
execute_sql(profile->dbname, sql, profile->ireg_mutex);
switch_safe_free(sql);
}
@@ -3495,17 +3502,18 @@
if (in) {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", "%s", note_txt);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", "%s", status_txt);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "%s", event_type);
switch_event_fire(&event);
}
} else {
if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_OUT) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "rpid", "%s", rpid);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s+%s@%s", SOFIA_CHAT_NAME, from_user, from_host);
@@ -3630,7 +3638,8 @@
switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
set_chat_hash(tech_pvt, sip);
-
+ switch_channel_set_variable(channel, "sip_fromuser", (char *) from->a_url->url_user);
+ switch_channel_set_variable(channel, "sip_fromhost", (char *) from->a_url->url_host);
if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
(char *) from->a_url->url_user,
profile->dialplan,
@@ -3840,10 +3849,12 @@
tech_pvt = switch_core_session_get_private(session);
}
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
- nua_event_name (event), status, phrase,
- session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
- );
+ if (status != 100 && status != 200) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "event [%s] status [%d][%s] session: %s\n",
+ nua_event_name (event), status, phrase,
+ session ? switch_channel_get_name(switch_core_session_get_channel(session)) : "n/a"
+ );
+ }
if ((profile->pflags & PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) {
sip_authorization_t const *authorization = NULL;
@@ -3982,6 +3993,7 @@
case nua_i_active:
case nua_i_ack:
case nua_i_terminated:
+ case nua_r_set_params:
break;
default:
@@ -4144,24 +4156,17 @@
switch_event_fire(&s_event);
}
- if (profile->pflags & PFLAG_PRESENCE) {
- if (!(profile->presence = switch_core_alloc(profile->pool, sizeof(*profile->presence)))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
- return NULL;
- }
- profile->presence->nh = nua_handle(profile->nua, NULL, SIPTAG_CONTACT_STR(profile->url), TAG_END());
-
- profile->presence->sofia_private.presence = profile->presence;
- nua_handle_bind(profile->presence->nh, &profile->presence->sofia_private);
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Creating presence for %s\n", profile->url);
- }
-
switch_mutex_lock(globals.hash_mutex);
switch_core_hash_insert(globals.profile_hash, profile->name, profile);
switch_mutex_unlock(globals.hash_mutex);
+ if (profile->pflags & PFLAG_PRESENCE) {
+ if (switch_event_create(&s_event, SWITCH_EVENT_ROSTER) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_NAME);
+ switch_event_fire(&s_event);
+ }
+ }
while(globals.running == 1) {
if (++ireg_loops >= IREG_SECONDS) {
@@ -4491,11 +4496,16 @@
char *from_host = switch_event_get_header(event, "orig-from-host");
char *contact_str = switch_event_get_header(event, "orig-contact");
char *exp_str = switch_event_get_header(event, "orig-expires");
+ char *rpid = switch_event_get_header(event, "orig-rpid");
long expires = (long)time(NULL) + atol(exp_str);
char *profile_name = switch_event_get_header(event, "orig-profile-name");
sofia_profile_t *profile;
char buf[512];
+ if (!rpid) {
+ rpid = "unknown";
+ }
+
if (!profile_name || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
return;
@@ -4503,17 +4513,19 @@
if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', %ld)",
- from_user,
- from_host,
- contact_str,
- expires);
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', '%q', %ld)",
+ from_user,
+ from_host,
+ contact_str,
+ rpid,
+ expires);
} else {
- sql = switch_mprintf("update sip_registrations set contact='%q', expires=%ld where user='%q' and host='%q'",
- contact_str,
- expires,
- from_user,
- from_host);
+ sql = switch_mprintf("update sip_registrations set contact='%q', rpid='%q', expires=%ld where user='%q' and host='%q'",
+ contact_str,
+ rpid,
+ expires,
+ from_user,
+ from_host);
}
@@ -4603,7 +4615,7 @@
switch_hash_index_t *hi;
void *val;
- if ((sql = switch_mprintf("select 0,'%q',* from sip_subscriptions where event='presence'"))) {
+ if ((sql = switch_mprintf("select 0,'unavailable','unavailable',* from sip_subscriptions where event='presence'"))) {
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -4625,25 +4637,83 @@
}
+
+static char *translate_rpid(char *in, char *ext)
+{
+ char *r = NULL;
+
+ if (in && (strstr(in, "null") || strstr(in, "NULL"))) {
+ in = NULL;
+ }
+
+ if (!in) {
+ in = ext;
+ }
+
+ if (!in) {
+ return NULL;
+ }
+
+ if (!strcasecmp(in, "dnd")) {
+ r = "busy";
+ }
+
+ if (ext && !strcasecmp(ext, "away")) {
+ r = "idle";
+ }
+
+ return r;
+}
+
static void pres_event_handler(switch_event_t *event)
{
sofia_profile_t *profile;
switch_hash_index_t *hi;
void *val;
char *from = switch_event_get_header(event, "from");
+ char *rpid = switch_event_get_header(event, "rpid");
char *status= switch_event_get_header(event, "status");
- char *show= switch_event_get_header(event, "show");
char *event_type = switch_event_get_header(event, "event_type");
- char *sql = NULL;
- char *user = NULL, *host = NULL;
+ char *sql = NULL, *sql2 = NULL;
+ char *euser = NULL, *user = NULL, *host = NULL;
char *errmsg;
char *resource;
switch_core_db_t *db;
+ if (rpid && !strcasecmp(rpid, "n/a")) {
+ rpid = NULL;
+ }
+ if (status && !strcasecmp(status, "n/a")) {
+ status = NULL;
+ }
+
+ if (rpid) {
+ rpid = translate_rpid(rpid, status);
+ }
+
+ if (!status) {
+ status = "Available";
+
+ if (rpid) {
+ if (!strcasecmp(rpid, "busy")) {
+ status = "Busy";
+ } else if (!strcasecmp(rpid, "unavailable")) {
+ status = "Idle";
+ } else if (!strcasecmp(rpid, "away")) {
+ status = "Idle";
+ }
+ }
+ }
+
if (event->event_id == SWITCH_EVENT_ROSTER) {
- sql = switch_mprintf("select 1,'%q',* from sip_subscriptions where event='presence'", status ? status : "Available");
+ if (from) {
+ sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence' and full_from like '%%%q%%'", status, rpid, from);
+ } else {
+ sql = switch_mprintf("select 1,'%q',%q',* from sip_subscriptions where event='presence'", status, rpid);
+ }
+
for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -4667,13 +4737,6 @@
return;
}
- if (status && !strcasecmp(status, "n/a")) {
- status = show;
- if (status && !strcasecmp(status, "n/a")) {
- status = NULL;
- }
- }
-
if (switch_strlen_zero(event_type)) {
event_type="presence";
}
@@ -4685,6 +4748,11 @@
if ((resource = strchr(host, '/'))) {
*resource++ = '\0';
}
+ if ((euser = strchr(user, '+'))) {
+ euser++;
+ } else {
+ euser = user;
+ }
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
return;
@@ -4701,19 +4769,12 @@
switch(event->event_id) {
case SWITCH_EVENT_PRESENCE_IN:
- if (!status) {
- status = "Available";
- }
-
- sql = switch_mprintf("select 1,'%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
- status , event_type, user, host);
+ sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
+ status , rpid, event_type, euser, host);
break;
case SWITCH_EVENT_PRESENCE_OUT:
- if (!status) {
- status = "Unavailable";
- }
- sql = switch_mprintf("select 0,'%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
- status, event_type, user, host);
+ sql = switch_mprintf("select 0,'%q','%q',* from sip_subscriptions where event='%q' and sub_to_user='%q' and sub_to_host='%q'",
+ status, rpid, event_type, euser, host);
break;
default:
break;
@@ -4734,18 +4795,19 @@
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_safe_free(sql);
-
- if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", user, host, user, host))) {
+
+
+ if ((sql2 = switch_mprintf("select 'sip+%q@%q',status,rpid from sip_registrations where user='%q' and host='%q'", euser, host, user, host))) {
switch_mutex_lock(profile->ireg_mutex);
- switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
+ switch_core_db_exec(db, sql2, sub_reg_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_core_db_close(db);
- switch_safe_free(sql);
+ switch_safe_free(sql2);
}
+ switch_core_db_close(db);
}
}
+ switch_safe_free(sql);
switch_safe_free(user);
}
1
0
20 Oct '06
Author: mikej
Date: Fri Oct 20 01:45:52 2006
New Revision: 3114
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
fix segfault?
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Fri Oct 20 01:45:52 2006
@@ -855,6 +855,10 @@
char *at, *resource;
char *user;
+ if (!s) {
+ return NULL;
+ }
+
if (!strchr(s, '/')) {
return NULL;
}
1
0
20 Oct '06
Author: ptinsley
Date: Thu Oct 19 23:33:49 2006
New Revision: 3113
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
Fix for broken trunk commit, setting contact_str size to the size of sql variable it's stored in [contact VARCHAR(1024)] + 1 for the null.
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Oct 19 23:33:49 2006
@@ -2669,7 +2669,7 @@
switch_event_t *s_event;
char *from_user = (char *) from->a_url->url_user;
char *from_host = (char *) from->a_url->url_host;
- char *contact_str[256] = "";
+ char contact_str[1025] = "";
char buf[512];
char *passwd = NULL;
uint8_t stale = 0, ret = 0, forbidden = 0;
1
0
19 Oct '06
Author: anthm
Date: Thu Oct 19 15:39:18 2006
New Revision: 3112
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
update
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Oct 19 15:39:18 2006
@@ -84,7 +84,8 @@
"CREATE TABLE sip_registrations (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
-" contact VARCHAR(255),\n"
+" contact VARCHAR(1024),\n"
+" status VARCHAR(255),\n"
" expires INTEGER(8)"
");\n";
@@ -97,7 +98,7 @@
" sub_to_user VARCHAR(255),\n"
" sub_to_host VARCHAR(255),\n"
" event VARCHAR(255),\n"
-" contact VARCHAR(255),\n"
+" contact VARCHAR(1024),\n"
" call_id VARCHAR(255),\n"
" full_from VARCHAR(255),\n"
" full_via VARCHAR(255),\n"
@@ -2668,7 +2669,7 @@
switch_event_t *s_event;
char *from_user = (char *) from->a_url->url_user;
char *from_host = (char *) from->a_url->url_host;
- char contact_str[256] = "";
+ char *contact_str[256] = "";
char buf[512];
char *passwd = NULL;
uint8_t stale = 0, ret = 0, forbidden = 0;
@@ -2820,7 +2821,7 @@
reg:
if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q',%ld)",
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Registered', %ld)",
from_user,
from_host,
contact_str,
@@ -2900,6 +2901,113 @@
}
+static int sub_reg_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+ sofia_profile_t *profile = (sofia_profile_t *) pArg;
+ char *from = argv[0];
+ char *status = argv[1];
+ switch_event_t *event;
+
+ if (switch_strlen_zero(status)) {
+ status = "Available";
+ }
+
+ if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "proto", "sip");
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "login", "%s", profile->url);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s", from);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "status", status);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "show", status);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "event_type", "presence");
+ switch_event_fire(&event);
+ }
+
+ return 0;
+}
+
+static int sub_callback(void *pArg, int argc, char **argv, char **columnNames)
+{
+ sofia_profile_t *profile = (sofia_profile_t *) pArg;
+ char *pl;
+ char *id, *note;
+ uint32_t in = atoi(argv[0]);
+ char *msg = argv[1];
+ char *proto = argv[2];
+ char *user = argv[3];
+ char *host = argv[4];
+ char *sub_to_user = argv[5];
+ char *sub_to_host = argv[6];
+ char *event = argv[7];
+ char *contact = argv[8];
+ char *callid = argv[9];
+ char *full_from = argv[10];
+ char *full_via = argv[11];
+ nua_handle_t *nh;
+ char *doing;
+ char *to;
+ char *open;
+
+
+ if (in) {
+ note = switch_mprintf("<dm:note>%s</dm:note>", msg);
+ doing="available";
+ open = "open";
+ } else {
+ note = NULL;
+ doing="unavailable";
+ open = "closed";
+ }
+
+ if (strcasecmp(proto, "sip")) {
+ /*encapsulate*/
+ id = switch_mprintf("sip:%s+%s+%s@%s", proto, sub_to_user, sub_to_host, host);
+ } else {
+ id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
+ }
+
+ to = switch_mprintf("sip:%s@%s", user, host);
+ pl = switch_mprintf("<?xml version='1.0' encoding='UTF-8'?>\r\n"
+ "<presence xmlns='urn:ietf:params:xml:ns:pidf'\r\n"
+ "xmlns:dm='urn:ietf:params:xml:ns:pidf:data-model'\r\n"
+ "xmlns:rpid='urn:ietf:params:xml:ns:pidf:rpid'\r\n"
+ "xmlns:c='urn:ietf:params:xml:ns:pidf:cipid'\r\n"
+ "entity='pres:%s'>\r\n"
+ "<tuple id='t6a5ed77e'>\r\n"
+ "<status>\r\n"
+ "<basic>%s</basic>\r\n"
+ "</status>\r\n"
+ "</tuple>\r\n"
+ "<dm:person id='p06360c4a'>\r\n"
+ "<rpid:activities>\r\n"
+ "<rpid:%s/>\r\n"
+ "<rpid:unknown/>\r\n"
+ "</rpid:activities>%s</dm:person>\r\n"
+ "</presence>", id, open, doing, note);
+
+ nh = nua_handle(profile->nua, NULL, TAG_END());
+
+
+ nua_notify(nh,
+ NUTAG_URL(contact),
+ SIPTAG_TO_STR(full_from),
+ SIPTAG_FROM_STR(to),
+ SIPTAG_CONTACT_STR(profile->url),
+ SIPTAG_CALL_ID_STR(callid),
+ SIPTAG_VIA_STR(full_via),
+ SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=3600"),
+ SIPTAG_EVENT_STR(event),
+ SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"),
+ SIPTAG_PAYLOAD_STR(pl),
+ TAG_END());
+
+ switch_safe_free(id);
+ switch_safe_free(note);
+ switch_safe_free(pl);
+ switch_safe_free(to);
+
+ return 0;
+}
+
static void sip_i_subscribe(int status,
char const *phrase,
nua_t *nua,
@@ -2926,7 +3034,10 @@
char *to_str = NULL;
char *full_from = NULL;
char *full_via = NULL;
+ switch_core_db_t *db;
+ char *errmsg;
+
if (from) {
from_user = (char *) from->a_url->url_user;
from_host = (char *) from->a_url->url_host;
@@ -3017,6 +3128,18 @@
TAG_END());
+ if (!(db = switch_core_db_open_file(profile->dbname))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+ goto end;
+ }
+ if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", to_user, to_host, to_user, to_host))) {
+ switch_mutex_lock(profile->ireg_mutex);
+ switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
+ switch_mutex_unlock(profile->ireg_mutex);
+ switch_core_db_close(db);
+ switch_safe_free(sql);
+ }
+
end:
if (event) {
@@ -3334,6 +3457,7 @@
switch_xml_t xml, note, person, tuple, status, basic;
switch_event_t *event;
uint8_t in = 0;
+ char *sql;
if ((xml = switch_xml_parse_str(payload->pl_data, strlen(payload->pl_data)))) {
char *status_txt = "", *note_txt = "";
@@ -3357,6 +3481,11 @@
}
}
+ if ((sql = switch_mprintf("update sip_registrations set status='%q' where user='%q' and host='%q'", note_txt, from_user, from_host))) {
+ execute_sql(profile->dbname, sql, profile->ireg_mutex);
+ switch_safe_free(sql);
+ }
+
event_type = sip_header_as_string(profile->home, (void *)sip->sip_event);
if (in) {
@@ -4370,7 +4499,7 @@
if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
- sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q',%ld)",
+ sql = switch_mprintf("insert into sip_registrations values ('%q','%q','%q','Regestered', %ld)",
from_user,
from_host,
contact_str,
@@ -4396,88 +4525,7 @@
}
}
-static int sub_callback(void *pArg, int argc, char **argv, char **columnNames){
- sofia_profile_t *profile = (sofia_profile_t *) pArg;
- char *pl;
- char *id, *note;
- uint32_t in = atoi(argv[0]);
- char *msg = argv[1];
- char *proto = argv[2];
- char *user = argv[3];
- char *host = argv[4];
- char *sub_to_user = argv[5];
- char *sub_to_host = argv[6];
- char *event = argv[7];
- char *contact = argv[8];
- char *callid = argv[9];
- char *full_from = argv[10];
- char *full_via = argv[11];
- nua_handle_t *nh;
- char *doing;
- char *to;
- char *open;
-
- if (in) {
- note = switch_mprintf("<dm:note>%s</dm:note>", msg);
- doing="available";
- open = "open";
- } else {
- note = NULL;
- doing="unavailable";
- open = "closed";
- }
-
- if (strcasecmp(proto, "sip")) {
- /*encapsulate*/
- id = switch_mprintf("sip:%s+%s+%s@%s", proto, sub_to_user, sub_to_host, host);
- } else {
- id = switch_mprintf("sip:%s@%s", sub_to_user, sub_to_host);
- }
-
- to = switch_mprintf("sip:%s@%s", user, host);
- pl = switch_mprintf("<?xml version='1.0' encoding='UTF-8'?>\r\n"
- "<presence xmlns='urn:ietf:params:xml:ns:pidf'\r\n"
- "xmlns:dm='urn:ietf:params:xml:ns:pidf:data-model'\r\n"
- "xmlns:rpid='urn:ietf:params:xml:ns:pidf:rpid'\r\n"
- "xmlns:c='urn:ietf:params:xml:ns:pidf:cipid'\r\n"
- "entity='pres:%s'>\r\n"
- "<tuple id='t6a5ed77e'>\r\n"
- "<status>\r\n"
- "<basic>%s</basic>\r\n"
- "</status>\r\n"
- "</tuple>\r\n"
- "<dm:person id='p06360c4a'>\r\n"
- "<rpid:activities>\r\n"
- "<rpid:%s/>\r\n"
- "<rpid:unknown/>\r\n"
- "</rpid:activities>%s</dm:person>\r\n"
- "</presence>", id, open, doing, note);
-
- nh = nua_handle(profile->nua, NULL, TAG_END());
-
-
- nua_notify(nh,
- NUTAG_URL(contact),
- SIPTAG_TO_STR(full_from),
- SIPTAG_FROM_STR(to),
- SIPTAG_CONTACT_STR(profile->url),
- SIPTAG_CALL_ID_STR(callid),
- SIPTAG_VIA_STR(full_via),
- SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=3600"),
- SIPTAG_EVENT_STR(event),
- SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"),
- SIPTAG_PAYLOAD_STR(pl),
- TAG_END());
-
- switch_safe_free(id);
- switch_safe_free(note);
- switch_safe_free(pl);
- switch_safe_free(to);
-
- return 0;
-}
-
static switch_status_t chat_send(char *from, char *to, char *subject, char *body, char *hint)
{
char buf[256];
@@ -4543,6 +4591,36 @@
return SWITCH_STATUS_SUCCESS;
}
+static void cancel_presence(void)
+{
+ char *sql, *errmsg = NULL;
+ switch_core_db_t *db;
+ sofia_profile_t *profile;
+ switch_hash_index_t *hi;
+ void *val;
+
+ if ((sql = switch_mprintf("select 0,'%q',* from sip_subscriptions where event='presence'"))) {
+ for (hi = switch_hash_first(apr_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
+ switch_hash_this(hi, NULL, NULL, &val);
+ profile = (sofia_profile_t *) val;
+ if (!(profile->pflags & PFLAG_PRESENCE)) {
+ continue;
+ }
+
+ if (!(db = switch_core_db_open_file(profile->dbname))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
+ continue;
+ }
+ switch_mutex_lock(profile->ireg_mutex);
+ switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
+ switch_mutex_unlock(profile->ireg_mutex);
+ switch_core_db_close(db);
+ }
+ switch_safe_free(sql);
+ }
+
+}
+
static void pres_event_handler(switch_event_t *event)
{
sofia_profile_t *profile;
@@ -4652,13 +4730,19 @@
switch_mutex_lock(profile->ireg_mutex);
switch_core_db_exec(db, sql, sub_callback, profile, &errmsg);
switch_mutex_unlock(profile->ireg_mutex);
- switch_core_db_close(db);
+ switch_safe_free(sql);
+
+ if ((sql = switch_mprintf("select 'sip+%q@%q',status from sip_registrations where user='%q' and host='%q'", user, host, user, host))) {
+ switch_mutex_lock(profile->ireg_mutex);
+ switch_core_db_exec(db, sql, sub_reg_callback, profile, &errmsg);
+ switch_mutex_unlock(profile->ireg_mutex);
+ switch_core_db_close(db);
+ switch_safe_free(sql);
+ }
}
-
}
switch_safe_free(user);
- switch_safe_free(sql);
}
@@ -4714,6 +4798,8 @@
SWITCH_MOD_DECLARE(switch_status_t) switch_module_shutdown(void)
{
+
+ cancel_presence();
switch_mutex_lock(globals.mutex);
if (globals.running == 1) {
1
0
[commit] r3111 - freeswitch/trunk/src/mod/event_handlers/mod_event_socket
by Freeswitch SVN 19 Oct '06
by Freeswitch SVN 19 Oct '06
19 Oct '06
Author: anthm
Date: Thu Oct 19 15:09:51 2006
New Revision: 3111
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
Log:
present from tony
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 Thu Oct 19 15:09:51 2006
@@ -502,12 +502,16 @@
switch_core_session_t *session;
char *uuid = cmd + 8;
-
if (uuid) {
while(*uuid == ' ') {
uuid++;
}
- strip_cr(uuid);
+
+ if (*uuid == '\r' || *uuid == '\n') {
+ uuid = NULL;
+ } else {
+ strip_cr(uuid);
+ }
}
if (!uuid) {
1
0
[commit] r3110 - freeswitch/trunk/src/mod/event_handlers/mod_event_socket
by Freeswitch SVN 19 Oct '06
by Freeswitch SVN 19 Oct '06
19 Oct '06
Author: anthm
Date: Thu Oct 19 14:52:46 2006
New Revision: 3110
Modified:
freeswitch/trunk/src/mod/event_handlers/mod_event_socket/mod_event_socket.c
Log:
present from pdt
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 Thu Oct 19 14:52:46 2006
@@ -593,10 +593,20 @@
} else if (!strncasecmp(cmd, "log", 3)) {
char *level_s;
+
+ //pull off the first newline/carriage return
strip_cr(cmd);
- level_s = cmd + 4;
+ //move past the command
+ level_s = cmd + 3;
+ //see if we got an argument
+ if(!switch_strlen_zero(level_s)) {
+ //if so move to the argument
+ level_s++;
+ }
+
+ //see if we lined up on an argument or not
if (switch_strlen_zero(level_s)) {
level_s = "debug";
}
1
0
19 Oct '06
Author: mikej
Date: Thu Oct 19 13:09:48 2006
New Revision: 3109
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
remove useless comment.
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Oct 19 13:09:48 2006
@@ -3520,7 +3520,6 @@
switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
}
// Loop thru Known Headers Here so we can do something with them
- // John Doe <sip:+19018577141@209.247.16.1>;party=calling;screen=yes;privacy=off
} else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
int argc, x, screen = 1;
char *mydata, *argv[10] = { 0 };
1
0
19 Oct '06
Author: mikej
Date: Thu Oct 19 13:04:58 2006
New Revision: 3108
Modified:
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
Get Alert-Info from inbound invite and set to the channel variable so that it can be passed through to the other end of the call if it is a sip call.
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Thu Oct 19 13:04:58 2006
@@ -3515,9 +3515,13 @@
for (un=sip->sip_unknown; un; un=un->un_next) {
+ if (!strncasecmp(un->un_name, "Alert-Info", 10)) {
+ if (!switch_strlen_zero(un->un_value)) {
+ switch_channel_set_variable(channel, "alert_info", (char *)un->un_value);
+ }
// Loop thru Known Headers Here so we can do something with them
// John Doe <sip:+19018577141@209.247.16.1>;party=calling;screen=yes;privacy=off
- if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
+ } else if (!strncasecmp(un->un_name, "Remote-Party-ID", 15)) {
int argc, x, screen = 1;
char *mydata, *argv[10] = { 0 };
if (!switch_strlen_zero(un->un_value)) {
1
0