Sophie

Sophie

distrib > Fedora > 13 > i386 > media > os > by-pkgid > cb7205622a1b72763262ee3e5a936b14 > files > 99

sems-1.1.1-6.fc12.i686.rpm

#######################################################################
#
# sw_prepaid_sip, the signalling-only prepaid engine
# Copyright (C) 2007 Sipwise GmbH
# Based on mycc, Copyright (C) 2002-2003 Fhg Fokus
#
# Author: Andreas Granig <agranig@sipwise.com>
#
########################################################################

How sw_prepaid_sip works
------------------------

The plugin extracts the headers "P-Caller-Uuid" and "P-Acc-Dest" as
caller and callee identifiers, respectively. Using these values,
it calls an accounting backend, which can defined in sw_prepaid_sip.conf,
and fetches the maximum call duration (per default, cc_acc is used as
billing backend, which is just a dummy plugin to show the most basic
concept of a billing backend).

If the credit is > 0, it uses the Request-Uri passed in the header "P-R-Uri"
and connects the callee using the outbound proxy passed in the header "P-Proxy".

When the call duration exceeds the credit, the call is terminated by SEMS.


A typical call flow would look like this, where (a) is the caller leg and
(b) the callee leg:

Caller    Proxy       SEMS      Callee
  |          |          |          |
  |  INV(a)  |          |          |
  |--------->|          |          |
  |  407(a)  |          |          |
  |<---------|          |          |
  |  INV(a)  |          |          |
  |--------->|          |          |
  |  100(a)  |          |          |
  |<---------|          |          |
  |          |  INV(a)  |          |
  |          |--------->|          |
  |          |  101(a)  |          |
  |          |<---------|          |
  |          |  INV(b)  |          |
  |          |<---------|          |
  |          |  INV(b)  |          |
  |          |-------------------->|
  |          |          |  180(b)  |
  |          |<--------------------|
  |          |  180(b)  |          |
  |          |--------->|          |
  |          |  180(a)  |          |
  |          |<---------|          |
  |  180(a)  |          |          |
  |<---------|          |          |
  |          |          |  200(b)  |
  |          |<--------------------|
  |          |  200(b)  |          |
  |          |--------->|          |
  |          |  200(a)  |          |
  |          |<---------|          |
  |  200(a)  |          |          |
  |<---------|          |          |
  |  ACK(a)  |          |          |
  |--------->|          |          |
  |          |  ACK(a)  |          |
  |          |--------->|          |
  |          |  ACK(b)  |          |
  |          |<---------|          |
  |          |  ACK(b)  |          |
  |          |-------------------->|
  |          |          |          |
  |          |          |          |


How to configure SEMS' sip proxy
--------------------------------

Modify the "tw_append" parameter of the "tm" option to pass the mandatory headers to
SEMS:

modparam("tm", "tw_append", 
  "prepaid_headers:hdr[P-Caller-Uuid];hdr[P-Proxy];hdr[P-R-Uri];hdr[P-Acc-Dest]")

Then add a proper block to pass prepaid calls to SEMS. In this example,
we assume that calls prefixed by "pre" are considered prepaid requests.
For ser-0.9.6 as SEMS' sip proxy, use something like:

if(uri =~ "sip:pre.+@")
{
	strip(3);
	if(!t_write_unix("/tmp/sems.sock","sw_prepaid_sip/prepaid_headers"))
	{
		xlog("L_ERR", "Error contacting SEMS - M=%rm R=%ru F=%fu T=%tu ID=%ci\n");
		t_reply("500","Could not contact B2BUA server");
	}
	break;
}

If you need to pass other headers from leg (a) to leg (b), you can add them to "tw_append" 
and they are copied to the other leg. This is for example necessary to pass the destination
URI to leg (b), which can then be extracted from the proxy and set accordingly.

How to configure a proxy to interact with sw_prepaid_sip
--------------------------------------------------------

If your proxy runs on IP 192.168.100.10:5060 and your SEMS' proxy on 192.168.100.10:5070, you
can pass leg (a) to the prepaid engine like this (assuming you use OpenSER >= 1.2.0 as 
sip proxy):

if(/* caller is prepaid */)
{
	/* use authentication user as caller uuid in prepaid engine */
	append_hf("P-Caller-Uuid: $au\r\n");

	/* use simplified R-URI as destination pattern in prepaid engine;
	   NOTE that cc_acc doesn't evaluate this field, but more 
	   advanced backends might do, so sw_prepaid_sip requires
	   this header */
	append_hf("P-Acc-Dest: $rU@$rd\r\n");

	/* the URI which is to be used by SEMS as outbound proxy for
	   call leg (b) - use our own here */
	append_hf("P-Proxy: sip:192.168.100.10:5060\r\n");

	/* the R-URI to be used to connect call leg (b) */
	append_hf("P-R-Uri: $ru\r\n");

	if($du != null)
	{
		/* if there's a D-Uri set, also send it to SEMS to correctly contact
		   call leg (b). NOTE you have to add this header in SEMS's sip proxy
		   config as "tw_append" value. */
		append_hf("P-D-Uri: $du\r\n");
	}

	/* point the R-Uri to SEMS' proxy and relay; this is just the most simple
	   example, but you can also use the LCR module for SEMS load balancing
	   and failover. */
	rewriteuri("sip:192.168.100.10:5070");
	t_relay();
}

In the above block, call leg (a) is passed to SEMS. Now we prepare a block to catch 
call leg (b) coming from SEMS. Add this at the very beginning of your proxy configuration.

/* usual sanity checks like msg-size and max-fwd, then do something like: */

if(src_ip == 192.168.100.10 && src_port == 5070 /* check if from SEMS */
	&& uri =~ ";sw_prepaid" /* this uri param is added by SEMS to detect prepaid calls */
	&& method == "INVITE" && !has_totag()) /* only process initial invites here */
{
	/* recover the R-Uri (maybe check for existence first!) */
	$ru = $hdr(P-R-Uri);

	/* recover destination Uri */
	if(is_present_hf("P-D-Uri"))
	{
		$du = $hdr(P-D-Uri);
		insert_hf("Route: <$hdr(P-D-Uri)>\r\n");
	}

	/* you might also consider removing the helper headers
	   by calling remove_hf(...) */

	/* relay to callee */
	t_relay();
}

Please note that the above example is a very basic one. For example, if you want to route
to PSTN gateways, you might want to add an informational header in leg (a) and evaluate
it in leg (b) to load a set of PSTN gateways instead of relaying to the R-Uri.

IMPORTANT: make sure to prevent black-hats from spoofing the SEMS proxy address to place
unauthenticated calls by using a private address for SEMS' sip proxy and by adding 
proper firewall rules on your ingress router.