[OpenSER-Users] Call transfer

Jan ONDREJ (SAL) ondrejj at salstar.sk
Thu Jan 31 09:02:10 CET 2008


Hello,

  thank you for reply.

On Thu, Jan 31, 2008 at 12:13:38AM +0100, Iñaki Baz Castillo wrote:
> El Miércoles, 30 de Enero de 2008, Jan ONDREJ (SAL) escribió:
> > On Wed, Jan 30, 2008 at 04:26:26PM -0500, Alex Balashov wrote:
> 
> Error: Have you investigated how REFER works? Two examples:

Yes. I know this theory.

> case 1)
> 
> 3 phones (A, B, C)
> 
> - A calls B and they speak.
> 
> - B wants to transfer the call to C. So B sends a REFER to A like this:
>   REFER sip:A at IP_A
>   Refer-To: sip:C at domain
> 
> - So A will receive that REFER and then A will generate an INVITE to C:
>   INVITE sip:C at domain
>   From: A at domain
> 
> - So in conclusion: a REFER in fact means: "please, invite this other user".

I am trying call transfer in this situation (case 1). It is not working in
my default cofnig (attached to this email, there are just removed
authentications to simply my testing).
Tryed blind transfer and also managed transfer.
One of three phnes still goes to undefined state (for example holding an
nonexistent call). In different situations different phones.

> case 2)
> 
> 2 phones (A, B) and a gateway.
> 
> - The gateway calls B and they speak.
> 
> - B wants to transfer to A so it sends a REFER to gateway like this:
>   REFER sip:gateway at IP_gateway
>   Refer-To: sip:A at domain
> 
> - So now the **gateway** should generate an INVITE to A. Unfortunatelly AFAIK 
> most of gateways won't allow it (and it sems logical to me).
> 
> What you need is a B2BUA between the gateway and phones. In this way the UAS 
> receiving the REFER will be the B2BUA (that you control) and not the gateway.

This is what I will need in future, but I am now experimenting only with
"case 1". I can't experiment on my active openser, so I configured another
openser and trying something simple (case 1). But it is not working. :(

> > An example configuration with call transfer support can be useful for other
> > users too, so it can be good to include it into openser distribution's
> > example configurations.
> 
> No, OpenSer is a SIP proxy, not a PBX or B2BUA, it just should route the REFER 
> according to RFC 3261 for in-dialog messages.

Hmm, theory. Does not work for me. After trying to change to asterisk
it works with my phones, but I am unable to do this with openser.
I don't like asterisk, so I want to configure openser for this situation.

> > >   OpenSER is a proxy, so it shouldn't really be "handling" referrals,
> > > just passing them back to the user agent/server (UAC/UAS) that will
> > > ultimately be taking care of that.
> >
> > It's not done by default config?
> 
> Yes, it's done. The problem you have is that you are sending the REFER to a 
> gateway.

Hmm, really? :(

		SAL
-------------- next part --------------
#
# $Id: openser.cfg 3284 2007-12-06 18:56:59Z bogdan_iancu $
#
# OpenSER basic configuration script
#     by Anca Vamanu <anca at voice-system.ro>
#
# Please refer to the Core CookBook at http://www.openser.org/dokuwiki/doku.php
# for a explanation of possible statements, functions and parameters.
#


####### Global Parameters #########

debug=3
log_stderror=no
log_facility=LOG_LOCAL0

#fork=yes
children=4

/* uncomment the following lines to enable debugging */
debug=6
#fork=no
log_stderror=yes

/* uncomment the next line to disable TCP (default on) */
#disable_tcp=yes

/* uncomment the next line to enable the auto temporary blacklisting of 
   not available destinations (default disabled) */
#disable_dns_blacklist=no

/* uncomment the next line to enable IPv6 lookup after IPv4 dns 
   lookup failures (default disabled) */
#dns_try_ipv6=yes

/* uncomment the next line to disable the auto discovery of local aliases
   based on revers DNS on IPs (default on) */
#auto_aliases=no

/* uncomment the following lines to enable TLS support  (default off) */
#disable_tls = no
#listen = tls:your_IP:5061
#tls_verify_server = 1
#tls_verify_client = 1
#tls_require_client_certificate = 0
#tls_method = TLSv1
#tls_certificate = "/usr/etc/openser/tls/user/user-cert.pem"
#tls_private_key = "/usr/etc/openser/tls/user/user-privkey.pem"
#tls_ca_list = "/usr/etc/openser/tls/user/user-calist.pem"


port=5060

/* uncomment and configure the following line if you want openser to 
   bind on a specific interface/port/proto (default bind on all available) */
#listen=udp:192.168.1.2:5060


####### Modules Section ########

#set module path
mpath="/usr/lib/openser/modules"

/* uncomment next line for MySQL DB support */
#loadmodule "mysql.so"
loadmodule "sl.so"
loadmodule "tm.so"
loadmodule "rr.so"
loadmodule "maxfwd.so"
loadmodule "usrloc.so"
loadmodule "registrar.so"
loadmodule "textops.so"
loadmodule "mi_fifo.so"
loadmodule "uri_db.so"
loadmodule "uri.so"
loadmodule "xlog.so"
#loadmodule "acc.so"
/* uncomment next lines for MySQL based authentication support 
   NOTE: a DB (like mysql) module must be also loaded */
#loadmodule "auth.so"
#loadmodule "auth_db.so"
/* uncomment next line for aliases support
   NOTE: a DB (like mysql) module must be also loaded */
#loadmodule "alias_db.so"
/* uncomment next line for multi-domain support
   NOTE: a DB (like mysql) module must be also loaded
   NOTE: be sure and enable multi-domain support in all used modules
         (see "multi-module params" section ) */
#loadmodule "domain.so"
/* uncomment the next two lines for presence server support
   NOTE: a DB (like mysql) module must be also loaded */
#loadmodule "presence.so"
#loadmodule "presence_xml.so"


# ----------------- setting module-specific parameters ---------------


# ----- mi_fifo params -----
modparam("mi_fifo", "fifo_name", "/tmp/openser_fifo")


# ----- rr params -----
# add value to ;lr param to cope with most of the UAs
modparam("rr", "enable_full_lr", 1)
# do not append from tag to the RR (no need for this script)
modparam("rr", "append_fromtag", 0)


# ----- rr params -----
modparam("registrar", "method_filtering", 1)
/* uncomment the next line to disable parallel forking via location */
# modparam("registrar", "append_branches", 0)
/* uncomment the next line not to allow more than 10 contacts per AOR */
#modparam("registrar", "max_contacts", 10)


# ----- uri_db params -----
/* by default we disable the DB support in the module as we do not need it
   in this configuration */
modparam("uri_db", "use_uri_table", 0)
modparam("uri_db", "db_url", "")


# ----- acc params -----
/* what sepcial events should be accounted ? */
#modparam("acc", "early_media", 1)
#modparam("acc", "report_ack", 1)
#modparam("acc", "report_cancels", 1)
/* by default ww do not adjust the direct of the sequential requests.
   if you enable this parameter, be sure the enable "append_fromtag"
   in "rr" module */
#modparam("acc", "detect_direction", 0)
/* account triggers (flags) */
#modparam("acc", "failed_transaction_flag", 3)
#modparam("acc", "log_flag", 1)
#modparam("acc", "log_missed_flag", 2)
/* uncomment the following lines to enable DB accounting also */
#modparam("acc", "db_flag", 1)
#modparam("acc", "db_missed_flag", 2)


# ----- usrloc params -----
modparam("usrloc", "db_mode",   0)
/* uncomment the following lines if you want to enable DB persistency
   for location entries */
#modparam("usrloc", "db_mode",   2)
#modparam("usrloc", "db_url",
#	"mysql://openser:openserrw@192.168.1.3/openser_1_3")


# ----- auth_db params -----
/* uncomment the following lines if you want to enable the DB based
   authentication */
#modparam("auth_db", "calculate_ha1", yes)
#modparam("auth_db", "password_column", "password")
#modparam("auth_db", "db_url",
#	"mysql://openser:openserrw@192.168.1.3/openser_1_3")
#modparam("auth_db", "load_credentials", "")


# ----- alias_db params -----
/* uncomment the following lines if you want to enable the DB based
   aliases */
#modparam("alias_db", "db_url",
#	"mysql://openser:openserrw@192.168.1.3/openser_1_3")


# ----- domain params -----
/* uncomment the following lines to enable multi-domain detection
   support */
#modparam("domain", "db_url",
#	"mysql://openser:openserrw@192.168.1.3/openser_1_3")
#modparam("domain", "db_mode", 1)   # Use caching


# ----- multi-module params -----
/* uncomment the following line if you want to enable multi-domain support
   in the modules (dafault off) */
#modparam("alias_db|auth_db|usrloc|uri_db", "use_domain", 1)


# ----- presence params -----
/* uncomment the following lines if you want to enable presence */
#modparam("presence|presence_xml", "db_url",
#	"mysql://openser:openserrw@192.168.1.3/openser_1_3")
#modparam("presence_xml", "force_active", 1)
#modparam("presence", "server_address", "sip:192.168.1.2:5060")


####### Routing Logic ########


# main request routing logic

route{

	if (!mf_process_maxfwd_header("10")) {
		sl_send_reply("483","Too Many Hops");
		exit;
	}

	if (has_totag()) {
		# sequential request withing a dialog should
		# take the path determined by record-routing
		if (loose_route()) {
			if (is_method("BYE")) {
				setflag(1); # do accouting ...
				setflag(3); # ... even if the transaction fails
			}
			route(1);
		} else {
			sl_send_reply("404","Not here");
		}
		exit;
	}

	#initial requests

	# CANCEL processing
	if (is_method("CANCEL"))
	{
		if (t_check_trans())
			t_relay();
		exit;
	}

	t_check_trans();

	# authenticate if from local subscriber (uncomment to enable auth)
	##if (!(method=="REGISTER") && from_uri==myself)
	##{
	##	if (!proxy_authorize("", "subscriber")) {
	##		proxy_challenge("", "0");
	##		exit;
	##	}
	##	if (!check_from()) {
	##		sl_send_reply("403","Forbidden auth ID");
	##		exit;
	##	}
	##
	##	consume_credentials();
	##	# caller authenticated
	##}

	# record routing
	if (!is_method("REGISTER|MESSAGE"))
		record_route();

	# account only INVITEs
	if (is_method("INVITE")) {
		setflag(1); # do accouting
	}
	if (!uri==myself)
	/* replace with following line if multi-domain support is used */
	##if (!is_uri_host_local())
	{
		append_hf("P-hint: outbound\r\n"); 
		# if you have some interdomain connections via TLS
		##if($rd=="tls_domain1.net") {
		##	t_relay("tls:domain1.net");
		##	exit;
		##} else if($rd=="tls_domain2.net") {
		##	t_relay("tls:domain2.net");
		##	exit;
		##}
		route(1);
	}

	# requests for my domain

	/* uncomment this if you want to enable presence server 
	   and comment the next 'if' block
	   NOTE: uncomment also the definition of route[2] from  below */
	##if( is_method("PUBLISH|SUBSCRIBE"))
	##		route(2);

	if (is_method("PUBLISH"))
	{
		sl_send_reply("503", "Service Unavailable");
		exit;
	}
	

	if (is_method("REGISTER"))
	{
		# authenticate the REGISTER requests (uncomment to enable auth)
		##if (!www_authorize("", "subscriber"))
		##{
		##	www_challenge("", "0");
		##	exit;
		##}
		##
		##if (!check_to()) 
		##{
		##	sl_send_reply("403","Forbidden auth ID");
		##	exit;
		##}

		if (!save("location"))
			sl_reply_error();

		exit;
	}

	if ($rU==NULL) {
		# request with no Username in RURI
		sl_send_reply("484","Address Incomplete");
		exit;
	}

	# apply DB based aliases (uncomment to enable)
	##alias_db_lookup("dbaliases");

	if (!lookup("location")) {
		switch ($retcode) {
			case -1:
			case -3:
				t_newtran();
				t_reply("404", "Not Found");
				exit;
			case -2:
				sl_send_reply("405", "Method Not Allowed");
				exit;
		}
	}

	# when routing via usrloc, log the missed calls also
	setflag(2);

	route(1);
}


route[1] {
	# for INVITEs enable some additional helper routes
	if (is_method("INVITE")) {
		t_on_branch("2");
		t_on_reply("2");
		t_on_failure("1");
	}

	if (!t_relay()) {
		sl_reply_error();
	};
	exit;
}


# Presence route
/* uncomment the whole following route for enabling presence
   NOTE: do not forget to enable the call of this route from the main
     route */
##route[2]
##{
##	if (!t_newtran())
##	{
##		sl_reply_error();
##		exit;
##	};
##
##	if(is_method("PUBLISH"))
##	{
##		handle_publish();
##		t_release();
##	}
##	else
##	if( is_method("SUBSCRIBE"))
##	{
##		handle_subscribe();
##		t_release();
##	}

#	exit;
#}


branch_route[2] {
	xlog("new branch at $ru\n");
}


onreply_route[2] {
	xlog("incoming reply\n");
}


failure_route[1] {
	if (t_was_cancelled()) {
		exit;
	}

	# uncomment the following lines if you want to block client 
	# redirect based on 3xx replies.
	##if (t_check_status("3[0-9][0-9]")) {
	##t_reply("404","Not found");
	##	exit;
	##}

	# uncomment the following lines if you want to redirect the failed 
	# calls to a different new destination
	##if (t_check_status("486|408")) {
	##	sethostport("192.168.2.100:5060");
	##	append_branch();
	##	# do not set the missed call flag again
	##	t_relay();
	##}
}


More information about the Users mailing list