<!-- Module User's Guide -->

<chapter>

	<title>&adminguide;</title>

	<section id="overview" xreflabel="Overview">
	<title>Overview</title>
	<para>
		This module provides the logic to convert a multi-stream
		SDP call, to multiple calls, each containing a subset of
		streams from the initial call. The module only handles the
		SIP signalling part of the call, without interfering with
		the media of the call, which will flow end-to-end. The only
		manipulation it does is at the SDP level to disable the
		media-streams that are not being used downstream.
	</para>
	<para>
		The logic is implemented on top of the B2B module, and
		de-multiplexes a B2B server (the initial call with
		multiple streams) to multiple B2B clients (with their own
		streams subset). In-dialog requests that come from the
		initial caller will be forked towards each client, and their
		replies aggregated back to the caller. The other side
		in-dialog requests are forwarded to the caller as if only
		their stream had changed. When a call is terminated from 
		the client side, the module can have different behaviors,
		according to the <xref linkend="param_client_bye_mode"/>
		parameter.
	</para>
	</section>
	<section id="use-cases" xreflabel="UseCases">
	<title>Use Cases</title>
	<para>
		A common scenario where this module can become useful is
		when configuring &osips; as a SIPREC SRS proxy. Using this
		module you can receive on one side SIPREC INVITEs, which
		usually have two or more SDP streams (one for each
		call/conference participants), and split/de-multiplex each
		stream in a new call downstream, usually towards a media
		server that is able to do call recording. This way the
		media server will have to handle calls that contain a
		single media stream.
	</para>
	<para>
		Another use case is balancing multiple streams to different
		media servers. For example, if you are offering both audio
		and video services, you can split a two-stream call (with
		an audio and video stream) to two different calls, and send
		them to be processed by different servers. This way you may
		have separated audio-dedicated processing media servers, as
		well as video-dedicated one. Of course, this can be achieved
		if you can process the streams separately, for example for
		recording.
	</para>
	</section>

	<section id="dependencies" xreflabel="Dependencies">
	<title>Dependencies</title>
	<section id="b2b_sdp_demux_modules_dependencies">
		<title>&osips; Modules</title>
		<para>
		The following modules must be loaded before this module:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>B2B_ENTITIES</emphasis> - Back-2-Back module
				used for handing server and client side calls.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>

	<section id="b2b_sdp_demux_external_dependencies">
		<title>External Libraries or Applications</title>
		<para>
		The following libraries or applications must be installed before
		running &osips; with this module loaded:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>None</emphasis>.
			</para>
			</listitem>
			</itemizedlist>
		</para>
	</section>
	</section>

	<section id="exported_parameters" xreflabel="Exported Parameters">
	<title>Exported Parameters</title>
	<section id="param_client_bye_mode" xreflabel="client_bye_mode">
		<title><varname>client_bye_mode</varname> (string)</title>
		<para>
			This parameter indicates how a BYE coming from the
			client side should be treated in the context of the
			upstream call.
		</para>
		<para>
		<para>
			Possible values are:
			<itemizedlist>
			<listitem>
			<para>
				<emphasis>disable</emphasis> - when a client
				terminates its call, the module will simply disable
				the media streams associated with its call, resulting
				in a re-INVITE upstream.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>terminate</emphasis> - when one client
				terminates its call, the module will terminate
				all other calls, including the upstream one.
			</para>
			</listitem>
			<listitem>
			<para>
				<emphasis>disable-terminate</emphasis> - same as
				disable, except that when the final stream is disabled,
				instead of a re-INVITE with all streams disabled,
				the module sends a BYE upstream.
			</para>
			</listitem>
			</itemizedlist>
		</para>
		<emphasis>
			Default value is <quote>disable</quote>.
		</emphasis>
		</para>
		<example>
		<title>Set <varname>client_bye_mode</varname> parameter</title>
		<programlisting format="linespecific">
...
modparam("b2b_sdp_demux", "client_bye_mode", "terminate")
...
</programlisting>
		</example>
	</section>
	</section>

	<section id="exported_functions" xreflabel="exported_functions">
		<title>Exported Functions</title>
		<section id="func_b2b_sdp_demux" xreflabel="b2b_sdp_demux()">
			<title>
			<function moreinfo="none">b2b_sdp_demux(URI[, [headers][, streams]])</function>
			</title>
			<para>
				Engages the B2B SDP De-Multiplexing scenario for the
				calls it has been triggered on.
			</para>
			<para>
				Parameters:
				<itemizedlist>
				<listitem><para>
					<emphasis>URI</emphasis> (string) - the URI where
					to send the newly generated calls
				</para></listitem>
				<listitem><para>
					<emphasis>headers</emphasis> (AVP, optional) - an
					AVP containing multiple values, each index
					corresponding to one of the new calls generated
					by the function. The number of values in the
					AVP should be equal to the number of calls
					resulted, otherwise it may lead to an unexpected
					behavior. If missing, no extra headers will be
					added.
				</para></listitem>
				<listitem><para>
					<emphasis>streams</emphasis> (AVP, optional) - an
					AVP containing multiple values, each value
					indicating the media stream index that should be
					used for the current client. If multiple streams
					should be used for a single call, they should
					be specified comma-separated (i.e.
					<emphasis>0,2</emphasis>). The number of AVP
					values represent the number of calls generated
					downstream. If the parameter is missing,
					a call will be generated for each stream present in
					the initial call.
				</para></listitem>
				</itemizedlist>
			</para>
			<para>
				This function can be used only from request route.
			</para>
			<example>
				<title>Use <function>b2b_sdp_demux()</function> to 
				handle an audio SIPREC call</title>
			<programlisting format="linespecific">
...
if (!has_totag() &amp;&amp; is_method("INVITE")) {
	$avp(headers) = "X-Leg: caller\r\n");
	$avp(headers) = "X-Leg: callee\r\n");
	b2b_sdp_demux("sip:media@localhost", $avp(headers));
}
...
	</programlisting>
			</example>
		</section>
	</section>

</chapter>
