<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="https://docs.telcobridges.com/mediawiki/skins/common/feed.css?303"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
		<id>https://docs.telcobridges.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexandre+Lussier</id>
		<title>TBwiki - User contributions [en]</title>
		<link rel="self" type="application/atom+xml" href="https://docs.telcobridges.com/mediawiki/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Alexandre+Lussier"/>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Special:Contributions/Alexandre_Lussier"/>
		<updated>2026-05-30T04:00:59Z</updated>
		<subtitle>User contributions</subtitle>
		<generator>MediaWiki 1.18.1</generator>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-23T15:30:05Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--span class=&amp;quot;hiddentext&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;Here is an example on how to calculate number of conferences and &amp;quot;slots&amp;quot; with the Dsp Wizard. This example also show you the options that are set on each type of &amp;quot;slots&amp;quot; (Stream: IVR, TDM: Call leg).&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:DspWizard.JPG|504px]]&lt;br /&gt;
&amp;lt;/span--&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-23T15:29:04Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;span class=&amp;quot;hiddentext&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;br /&amp;gt;Here is an example on how to calculate number of conferences and &amp;quot;slots&amp;quot; with the Dsp Wizard. This example also show you the options that are set on each type of &amp;quot;slots&amp;quot; (Stream: IVR, TDM: Call leg).&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:DspWizard.JPG|504px]]&lt;br /&gt;
&amp;lt;/span&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T16:00:32Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here is an example on how to calculate number of conferences and &amp;quot;slots&amp;quot; with the Dsp Wizard. This example also show you the options that are set on each type of &amp;quot;slots&amp;quot; (Stream: IVR, TDM: Call leg).&amp;lt;br /&amp;gt;&lt;br /&gt;
[[File:DspWizard.JPG|504px]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T16:00:19Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here is an example on how to calculate number of conferences and &amp;quot;slots&amp;quot; with the Dsp Wizard. This example also show you the options that are set on each type of &amp;quot;slots&amp;quot; (Stream: IVR, TDM: Call leg).&lt;br /&gt;
[[File:DspWizard.JPG|504px]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/File:DspWizard.JPG</id>
		<title>File:DspWizard.JPG</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/File:DspWizard.JPG"/>
				<updated>2012-08-20T15:59:14Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: An example of use of the Dsp Wizard&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;An example of use of the Dsp Wizard&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T15:57:55Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here is an example on how to calculate number of conferences and &amp;quot;slots&amp;quot; with the Dsp Wizard. This example also show you the options that are set on each type of &amp;quot;slots&amp;quot; (Stream: IVR, TDM: Call leg).&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T15:23:58Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: &lt;br /&gt;
:608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 2 call legs in a conference and play/record activated: &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): &lt;br /&gt;
:680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: &lt;br /&gt;
:168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: &lt;br /&gt;
:160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T15:22:55Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br /&amp;gt;Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: 608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 2 call legs in a conference and play/record activated: 680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): 680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: 168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: 160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T15:22:41Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
Here are capacity results, depending of conference type:&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: 608 conferences and 1,824 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 2 call legs in a conference and play/record activated: 680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): 680 conferences and 2,040 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: 168 conferences and 2,016 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;br /&gt;
- 12 call legs in a conference and no play/record: 160 conferences and 1,920 &amp;quot;slots&amp;quot;&amp;lt;br /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-20T15:22:19Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 1,824 conference &amp;quot;slots&amp;quot; (thus a total of 29,184 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;br /&gt;
&lt;br /&gt;
Here are capacity results, depending of conference type:&lt;br /&gt;
&lt;br /&gt;
- 3 call legs in a conference and no play/record: 608 conferences and 1,824 &amp;quot;slots&amp;quot;&lt;br /&gt;
- 2 call legs in a conference and play/record activated: 680 conferences and 2,040 &amp;quot;slots&amp;quot;&lt;br /&gt;
- 1 call leg in a conference and play and record activated (can record what is played): 680 conferences and 2,040 &amp;quot;slots&amp;quot;&lt;br /&gt;
- 11 call legs in a conference and play/record activated: 168 conferences and 2,016 &amp;quot;slots&amp;quot;&lt;br /&gt;
- 12 call legs in a conference and no play/record: 160 conferences and 1,920 &amp;quot;slots&amp;quot;&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Caf_Mixer_Events</id>
		<title>CAF: Caf Mixer Events</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Caf_Mixer_Events"/>
				<updated>2012-08-13T16:00:19Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Inserting / removing call legs (or other mixers) from the mixer: */  update new call back&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Events received from mixers by the CTBCAFCallFlow object ==&lt;br /&gt;
&lt;br /&gt;
The call flow object (as well as all it's behaviors) receive the following events from it's mixers (please refer to the header file ITBCAFCallFlowMixer.hpp for more information on each of these functions):&lt;br /&gt;
&lt;br /&gt;
=== Initialization and termination of mixer objects: ===&lt;br /&gt;
 - OnMixerInit()&lt;br /&gt;
 - OnMixerCreated()&lt;br /&gt;
 - OnMixerTerminated()&lt;br /&gt;
 - OnMixerFreed()&lt;br /&gt;
 - OnMixerAttributeChanged()&lt;br /&gt;
&lt;br /&gt;
=== Inserting / removing call legs (or other mixers) from the mixer: ===&lt;br /&gt;
 - OnMixerLegJoinDone()&lt;br /&gt;
 - OnMixerMixerJoinDone()&lt;br /&gt;
 - OnMixerLegUnjoinDone()&lt;br /&gt;
 - OnMixerMixerUnjoinDone()&lt;br /&gt;
&lt;br /&gt;
=== Re-synchronization with [[Toolpack_Application:toolpack_engine|toolpack_engine]]: ===&lt;br /&gt;
 - OnMixerSyncDone()&lt;br /&gt;
 - OnMixerSyncLost()&lt;br /&gt;
&lt;br /&gt;
=== Timers or custom events: ===&lt;br /&gt;
 - OnMixerEvent()&lt;br /&gt;
&lt;br /&gt;
=== Errors detected by [[Toolpack_Application:toolpack_engine|toolpack_engine]]: ===&lt;br /&gt;
 - OnMixerError()&lt;br /&gt;
&lt;br /&gt;
==== Playing/recording audio ====&lt;br /&gt;
 - OnMixerStreamPlayingStarted()&lt;br /&gt;
 - OnMixerStreamRecordingStarted()&lt;br /&gt;
 - OnMixerStreamPlayingDone()&lt;br /&gt;
 - OnMixerStreamRecordingDone()&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-13T15:47:10Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TMedia conference capacity */  add TMS needs if mixed on multiple adapters&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 2,000 conference &amp;quot;slots&amp;quot; (thus a total of 32,000 for TMG7800 system).&lt;br /&gt;
If mixers need to be joined with call legs from different adapters, a TMS switch is needed.&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-13T15:44:47Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Resource usage of mixers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, recording file) use one mixer slot. It is possible to record and play at the same time, but the recording does not contain what is played on the mixer&lt;br /&gt;
:* It is possible to have a recording that contains what is played on the mixer, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 2,000 conference &amp;quot;slots&amp;quot; (thus a total of 32,000 for TMG7800 system).&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/File:Mixer_internal.png</id>
		<title>File:Mixer internal.png</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/File:Mixer_internal.png"/>
				<updated>2012-08-13T15:25:28Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: uploaded a new version of &amp;amp;quot;File:Mixer internal.png&amp;amp;quot;: change active and inactive speaker for dominant and silent speaker to be coherent in our doc&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Diagram of how a mixer works internally with:&lt;br /&gt;
- Active talkers&lt;br /&gt;
- Inactive talkers&lt;br /&gt;
- Listeners&lt;br /&gt;
- Stream Server Play/Record&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-13T15:09:13Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Resource usage of mixers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, playing tone, recording file) use one mixer slot&lt;br /&gt;
:* It is possible to play a file on a mixer and record that mixer at the same time, but it uses one more mixer slot (total of 2 slots)&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 2,000 conference &amp;quot;slots&amp;quot; (thus a total of 32,000 for TMG7800 system).&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/AudioMixers</id>
		<title>AudioMixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/AudioMixers"/>
				<updated>2012-08-13T15:08:17Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Resource usage of mixers */  talk about the possibility to record and play at the same time on a mixer&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Toolpack audio mixers ==&lt;br /&gt;
A mixer is used to mix the audio of multiple sources (call legs, playing audio file, tone generator...)&lt;br /&gt;
&lt;br /&gt;
=== Typical usage of audio mixers ===&lt;br /&gt;
Audio mixers can be used, among other things, to:&lt;br /&gt;
* Build conferences&lt;br /&gt;
* Insert background music to a conversation&lt;br /&gt;
* Record both sides of the conversation into a single recorded file.&lt;br /&gt;
&lt;br /&gt;
=== Joining audio source to a mixer ===&lt;br /&gt;
There are 2 ways to join a mixer:&lt;br /&gt;
* Join as a listener only&lt;br /&gt;
* Join as a speaker. Speakers can be active / or inactive (inactive speakers are not mixed, but monitored for voice activity)&lt;br /&gt;
&lt;br /&gt;
[[File:mixer_internal.png|504px]]&lt;br /&gt;
&lt;br /&gt;
=== Maximum call legs per mixer ===&lt;br /&gt;
The mixer has the following capabilities:&lt;br /&gt;
* The mixer can have any number of listeners (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
* The mixer can have any number of speakers (up to maximum number of call legs supported by the TMedia system)&lt;br /&gt;
** Among these speakers, up to 10 will be considered as &amp;quot;active&amp;quot; (the 10 from which voice was received the most recently)&lt;br /&gt;
** Among these 10 active speakers, the audio from dominant N speakers will be mixed (N can be configured per mixer)&lt;br /&gt;
&lt;br /&gt;
=== Resource usage of mixers ===&lt;br /&gt;
* An active speaker uses one mixer slot (up to 10 per conference)&lt;br /&gt;
* All non-active speakers use one mixer slot (although there is no per-conference limit)&lt;br /&gt;
* All listeners ''share'' the same mixer slot&lt;br /&gt;
* IVR on the mixer (playing file, playing tone, recording file) use one mixer slot&lt;br /&gt;
:* It is possible to play a file on a mixer and record that mixer at the same time, but it uses one more mixer slot&lt;br /&gt;
&lt;br /&gt;
=== TMedia conference capacity ===&lt;br /&gt;
In order to use conferences, TMedia must be equipped with DSPs.&lt;br /&gt;
Each TMG3200 or TMG7800 unit can be equipped with DSPs for 2,000 conference &amp;quot;slots&amp;quot; (thus a total of 32,000 for TMG7800 system).&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Cmc_Mixers</id>
		<title>CAF: Working With Cmc Mixers</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Cmc_Mixers"/>
				<updated>2012-08-13T14:50:22Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Mixer Synchronization on Failover */  change order of mixer sync&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Audio Mixers Definition ==&lt;br /&gt;
Audio mixers are used to mix audio from multiple call legs and provide mixed output to each call leg.&lt;br /&gt;
At any time during a call flow the application can join call legs to one (or multiple) audio mixer.&lt;br /&gt;
&lt;br /&gt;
== TMedia concepts and density ==&lt;br /&gt;
Please read the following page for general information about TMedia Mixers:&lt;br /&gt;
[[AudioMixers|Audio Mixers]]&lt;br /&gt;
&lt;br /&gt;
== CTBCMCMixer class ==&lt;br /&gt;
An audio mixer is represented by an instance of the CTBCMCMixer class.&lt;br /&gt;
Call legs ([[CAF:_Working_With_Cmc_Call_Legs|CTBCMCLeg]]) can be joined to this audio mixer as speakers, listeners, or both.&lt;br /&gt;
&lt;br /&gt;
In addition to call legs joining/unjoining, the CTBCMCMixer class allows some media functions such as playing audio files to all listeners of the mixer, or recording all active speakers of the mixer.&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the mixer attributes, and the way different call legs are joined to the mixer (speaker/listener)&lt;br /&gt;
&lt;br /&gt;
It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse the base class CTBCMCMixer with the class CTBCAFMixer. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs and mixers.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Mixer Actions in CAF ==&lt;br /&gt;
All actions requested on a mixer are executed asynchronously. For each action '''DoSomething()''' on a mixer,  a corresponding '''OnSomethingResponse()''' event will be received on the mixer once Toolpack starts processing the command. If the '''OnSomethingResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnMixerError()''' will be called. In some cases, when the action is completed, an event will be received on the mixer ('''OnSomethingDone()''' for example).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play an audio file on the mixer (heard by all legs listening to this mixer), one would call '''MixerPlayStream()'''. It would then almost immediately receive the '''OnMixerPlayStreamResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start configuring the resources to play on the mixer. Once the play has started, the user will receive an event '''OnMixerStreamPlayingStarted()''', and when it finished playing (or failed to start), the user will receive an '''OnMixerStreamPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
== Mixer Creation ==&lt;br /&gt;
Creating a mixer is always done through the definition of a ''mixer attribute''. The values entered in the ''mixer attribute'' will define how the mixer behaves, and will influence resource reservation.&lt;br /&gt;
&lt;br /&gt;
=== Preparing Mixer Attributes ===&lt;br /&gt;
&lt;br /&gt;
The class CTBCMC_MIXER_ATTRIBUTE defines available attributes to configure an audio mixer. Default parameters are provided for standard usage, though parameters may be changed to control the behavior more precisely.&lt;br /&gt;
Example mixer attributes are:&lt;br /&gt;
* Reserve IVR resource (else add it dynamically when needed)&lt;br /&gt;
* Reserve 'listener-only' slot (else added dynamically upon joining of first 'listener-only' leg)&lt;br /&gt;
* Reserve speaker slots (else add speaker slots dynamically when needed)&lt;br /&gt;
* Maximum number of active &amp;quot;dominant&amp;quot; speakers (maximum number of audio sources mixed together at a given time, based on loudest speakers)&lt;br /&gt;
* Noise floor (for considering inactive speaker as now talking)&lt;br /&gt;
* Noise suppression limit (for removal of background noise from active speakers)&lt;br /&gt;
* Target power for conference output&lt;br /&gt;
* Loss limit / Gain limit (limiting the audio level adjustments allowed from speaker legs to reach the target power)&lt;br /&gt;
Note: Please refer to header file '''tbcmc_mixer.hpp''' for a more complete documentation on all available mixer attributes.&lt;br /&gt;
&lt;br /&gt;
Once a mixer is created, Toolpack will manage reservation of DSP resources on a TMedia, and will manage connecting legs to the mixer (listeners, or speakers). When call legs are joined or unjoined from the mixer, Toolpack will automatically re-size the DSP resource if appropriate (with a minimum size determined by the 'reserve' mixer attributes).&lt;br /&gt;
And thus, the application does not have to deal with resource management distribution among TMedia units.&lt;br /&gt;
For more information about capacity of TMedia units (in number of conference &amp;quot;slots&amp;quot;), please refer to this page: [[AudioMixers#Resource_usage_of_mixers|Audio Mixers -&amp;gt; Resource usage]]&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_MIXER_ATTRIBUTE ptrMixerAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrMixerAttribute = tbnew CTBCMC_MIXER_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrMixerAttribute-&amp;gt;SetReserveIvrSlot( TBX_TRUE );&lt;br /&gt;
  ptrMixerAttribute-&amp;gt;-&amp;gt;SetReserveListenerSlot( TBX_FALSE );&lt;br /&gt;
  ptrMixerAttribute-&amp;gt;SetNbReservedActiveSpeakerSlots( 3 );&lt;br /&gt;
  ptrMixerAttribute-&amp;gt;SetNbDominantSpeakers( 3 );&lt;br /&gt;
  ptrMixerAttribute-&amp;gt;SetNoiseFloor( TBCMC_VAD_NOISE_FLOOR_LEVEL_MINUS_30_DBM );&lt;br /&gt;
  ...&lt;br /&gt;
&lt;br /&gt;
=== Creating the Mixer ===&lt;br /&gt;
Once the mixer attributes have been filled, creating the mixer in Toolpack is only a matter of creating a CTBCMCMixer object and calling '''MixerCreate()''' on it. At that moment a message is sent to Toolpack system to allocate the mixer on the hardware.&lt;br /&gt;
&lt;br /&gt;
  pCallMixer = new CTBCMCMixer( 0 /* or MixerId from OnMixerSync() */, ptrMixerAttribute, this, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallMixer -&amp;gt;MixerCreate();&lt;br /&gt;
&lt;br /&gt;
Once the mixer has finished being allocated on hardware, the function '''OnMixerCreated()''' will be called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Mixer Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a mixer is a 2 steps process:&lt;br /&gt;
# Call '''MixerTerminate()'''&lt;br /&gt;
# Ask for mixer object free upon '''OnMixerTerminated()''' callback function&lt;br /&gt;
&lt;br /&gt;
When '''MixerTerminate()''' is called, the Toolpack framework will start destroying the mixer (including unjoining any call leg that was joined to it). Once the mixer hardware resources have been deallocated, Toolpack will call '''OnMixerTerminated()'''. Receiving that event means that the mixer no more exists in Toolpack, and the object can thus be freed. Any time after '''OnMixerTerminated()''' (or within that function), the application is responsible to call method '''FreeMixer()''', which will eventually cause the mixer's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface function '''Free''' to be called. The ITBCMCFreeListener to use can be specified either in the CTBCMCMixer constructor and by calling '''SetFreeListener()'''. The mixer can be it's own ''FreeListener'', in which it just 'delete' itself. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the mixer is deleted. An example could be the case where the mixer object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that mixer termination be initiated by Toolpack. This can happen in the event of sudden media resource unavailability on hardware, or if the application gets disconnected from Toolpack engine. In that cases, the callback '''OnMixerTerminated()''' is called. On reception of this event, the application should also acknowledge termination by calling '''FreeMixer()'''.&lt;br /&gt;
&lt;br /&gt;
== Mixer Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted, or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs, links and mixers:&lt;br /&gt;
* Callback '''OnCallLegSync()''' lists all legs that were retrieved from Toolpack&lt;br /&gt;
* Callback '''OnMixerSync()''' lists all mixers that were retrieved from Toolpack, along with list of legs joined to each mixer.&lt;br /&gt;
* Callback '''OnLinkSync()''' lists all joined leg pairs that were retrieved from Toolpack&lt;br /&gt;
* Callback '''OnMixerLinkSync()''' lists all legs joined to mixers, and mixers joined to mixers.&lt;br /&gt;
&lt;br /&gt;
The course of action to take when receiving a leg or mixer synchronization event depends on the ability of the application to resynchronize or rebuild its own states.&lt;br /&gt;
&lt;br /&gt;
A typical re-synchronization scenario would be similar to:&lt;br /&gt;
* Application receives all '''OnCallLegSync()''' callbacks, for each a new object of type CTBCMCLeg is created&lt;br /&gt;
* Application receives all '''OnMixerSync()''' callbacks, and for each a new object of type CTBCMCMixer is created.&lt;br /&gt;
* Application receives all '''OnLinkSync()''' callbacks, and for each re-builds the association between the CTBCMCLeg by calling function '''SetJoined()''' of one of the legs.&lt;br /&gt;
* Application receives all '''OnMixerLinkSync()''' callbacks, and for each re-builds the association between legs and mixers by calling function '''MixerSetJoined()'''.&lt;br /&gt;
* Any leg, link or mixer that the application does not wish to keep is destroyed ('''RefuseLeg''', '''RefuseLink''', '''RefuseMixer''', or '''RefuseMixerLink''')&lt;br /&gt;
&lt;br /&gt;
When all legs, links and mixers have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. Event '''OnSyncDone()''' is also called on each re-synchronized leg, and '''OnMixerSyncDone()''' on each re-synchronized mixer.&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Web_Portal_Tutorial_Guide_v2.5</id>
		<title>Web Portal Tutorial Guide v2.5</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Web_Portal_Tutorial_Guide_v2.5"/>
				<updated>2011-10-28T14:51:05Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: change link order&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
This guide is designed to provide users with a scenario-based approach to installing  [[Tmedia]] and [[Tdev]] systems, using the Web Portal configuration tool. This means that users must first go through the steps that are general to all installations, and subsequently follow the instructions that are specific to their particular application scenario (this corresponds to the type of service, and hardware system being set up).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
This document assumes that the [[Tmedia]] or [[Tdev]] devices are installed as described in their Quick Reference Guides, and in the case of the Tmedia system communication has been established with the control network.&lt;br /&gt;
&lt;br /&gt;
(Note: Tmedia devices are shipped with the Tmedia Web Portal pre-installed, while Tdev devices require that Toolpack be installed as described in the [http://download.distribution.telcobridges.com/documentation/TMP6400_Installation_Guide.pdf TMP6400 Installation Guide].)&lt;br /&gt;
&lt;br /&gt;
Furthermore, in the case of a Tdev device and the initial configuration of the [[Toolpack]] application server, the following will have been provided:&lt;br /&gt;
*The Tdev device to which the Web Portal will first connect.&lt;br /&gt;
*The Tdev device will have been pre-configured with its physical TDM interface.&lt;br /&gt;
*The serial number of the Tdev device will have been entered into the configuration file.&lt;br /&gt;
*The application software for the Tdev device will have been pre-installed on the Toolpack application server, as described in the [http://download.distribution.telcobridges.com/documentation/TMP6400_Installation_Guide.pdf TMP6400 Installation Guide].&lt;br /&gt;
&lt;br /&gt;
This document also assumes familiarity with topics, such as [[ISDN]] signaling, [[SIP]] signaling, [[SS7]], [[CAS|CAS R2]] signaling, and [[SIGTRAN]] signaling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Key Concepts==&lt;br /&gt;
*'''System:''' A system is defined as the complete solution that is designed for a network. If a system solution is comprised of 4 TMP6400’s and a TMS1600, then the combination of these TelcoBridges devices is termed a system.&lt;br /&gt;
*'''Hardware:''' Each TelcoBridges devices, whether it is a TMP6400, TMG3200, or TMS1600 is referred to as a hardware device or hardware adapter.&lt;br /&gt;
*'''Line Interface:''' The physical TDM module installed on the TelcoBridges device is referred to as a line interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== General Web Portal Applications ==&lt;br /&gt;
&lt;br /&gt;
'''''IMPORTANT!''''' The Topics covered in the following table are common to &amp;lt;u&amp;gt;all&amp;lt;/u&amp;gt; TMedia installations. Therefore, this section should be consulted before moving on to any other. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; '''Topics covered here:''' &lt;br /&gt;
&lt;br /&gt;
*The basic knowledge needed to properly navigate through the Web Portal '''(A)'''. &lt;br /&gt;
*The fundamentals of user account management and permission masks '''(B)'''. &lt;br /&gt;
*The initial steps required for first starting the Web Portal, and verifying that it is functioning properly '''(C)'''. &lt;br /&gt;
*The process involved in backing up your database for the first time '''(D)'''. &lt;br /&gt;
*The process involved in first configuring your IP interfaces '''(E)'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic A) &amp;lt;br&amp;gt;Web Portal Basics &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic B) &amp;lt;br&amp;gt;Log-on and User Access Levels &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic C) &amp;lt;br&amp;gt;Application Start-up and Verification &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic D) &amp;lt;br&amp;gt;Database Backup&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Navigating the Web Portal|Navigating the Web Portal]] &lt;br /&gt;
*[[Typographic conventions|Typographic Conventions]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Connecting to the Web Server and logging on to the web portal|Connect to the web server and log on to the Web Portal]] &lt;br /&gt;
*[[Toolpack:User access|User Access]] &lt;br /&gt;
**[[Toolpack v2.5:Viewing the User List|Viewing the User List]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a New User|Creating a New User]] &lt;br /&gt;
**[[Toolpack v2.5:Deleting a User|Deleting a User]] &lt;br /&gt;
**[[Toolpack v2.5:Logging Off Toolpack|Logging Off]] &lt;br /&gt;
*[https://forums.telcobridges.com/viewtopic.php?f=12&amp;amp;t=248&amp;amp;p=1101&amp;amp;hilit=privilege#p1101 User privilege level]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Viewing the List of Installed Applications|Viewing the List of Installed Applications]] &lt;br /&gt;
*[[Toolpack v2.5:Starting an Application|Starting an Application]] &lt;br /&gt;
*[[Toolpack:Verifying that an Application is Operating|Verifying that an Application is Operating]] &lt;br /&gt;
**[[Toolpack v2.5:Verifying the Application Path|Verifying the Application Path]] &lt;br /&gt;
*[[Toolpack v2.5:Activating the Configuration|Activating the Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Status Menus:Applications|Verifying status]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Database Backup|Carrying out a First Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Downloading a Database Backup|Downloading a Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Uploading a Database Backup|Uploading a Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Restoring a Database Backup|Restoring a Database Backup]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic E) &amp;lt;br&amp;gt;Configure IP Interfaces&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Configuring IP Interfaces|Configure IP Interfaces]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=ISDN-SIP Gateway Configuration=&lt;br /&gt;
&lt;br /&gt;
The following tables contain a typical configuration scenario for an [[ISDN]] to [[SIP]] gateway. This type of installation allows for the transfer of information from traditional [[ISDN]] signaling to [[SIP]] protocol for [[VoIP]] applications. Please follow each step one after another as these are listed in logical order.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The steps are as follows:'''&lt;br /&gt;
&lt;br /&gt;
*1) Log On and Create a New Configuration&lt;br /&gt;
*2) Allocate Physical Interfaces&lt;br /&gt;
*3) Configure ISDN-PRI Signaling&lt;br /&gt;
*4) Configure Clocking Source&lt;br /&gt;
*5) Configure SIP Signaling&lt;br /&gt;
*6) Configure Codecs and Tone Detection&lt;br /&gt;
*7) Configure Network Access Points (NAPs)&lt;br /&gt;
*8) Create Call Routing Rules&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;'''IMPORTANT!'''&amp;lt;/b&amp;gt; After completing the setup process, remember to '''activate the configuration''', as outlined in the [[Web_Portal_Tutorial_Guide_v2.5#General_Web_Portal_Applications|General Web Portal Applications section]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Log On and Create a New Configuration&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Allocate Physical Interfaces&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Configure ISDN-PRI Signaling&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configure Clocking Source&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Connecting_to_the_Web_Server_and logging on to the web portal|Connect to the web server and log on to the Web Portal]]&lt;br /&gt;
*[[Toolpack_v2.5:Copying_the_Default_Configuration|Copy the default configuration]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create a new line interface]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create a new line service]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Configuring_an_ISDN_Stack|Configure an ISDN stack]]&lt;br /&gt;
OR&amp;lt;br/&amp;gt;&lt;br /&gt;
*[[Configure NFAS]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Defining_a_Clocking_Source|Define a clocking source]] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configure SIP Signaling&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 6) &amp;lt;br&amp;gt;Configure Codecs and Tone Detection&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 7) &amp;lt;br&amp;gt;Configure Network Access Points (NAPs)&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 8) &amp;lt;br&amp;gt;Create Call Routing Rules&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create an IP port range]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Stack|Create a SIP stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Transport_Server|Create a SIP transport server]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Service_Access_Point_(SAP)|Create a service access point (SAP)]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Accessing_Codec_and_Tone_Detection_Profiles_and_Validating_Settings|Access profiles and validate settings]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Allocating_an_ISDN_Network_Access_Point_(NAP)|Allocate an ISDN NAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_SIP_Network_Access_Point_(NAP)|Allocate a SIP NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_First_Call_Route|Create a first call route]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring SS7=&lt;br /&gt;
&lt;br /&gt;
The following table contains information on configuring the [[SS7]] signaling protocol.&lt;br /&gt;
The various control layers of the [[SS7]] protocol are listed individually in each column. These layers are:&lt;br /&gt;
&lt;br /&gt;
* [[MTP2_Layer|MTP2]] layer '''(Step 1)'''&lt;br /&gt;
* [[MTP3_Layer|MTP3]] layer '''(Step 2)'''&lt;br /&gt;
* [[ISUP]] layer '''(Step 3)'''&lt;br /&gt;
* [[SCCP]] layer '''(Step 4)'''&lt;br /&gt;
* [[TCAP]] layer '''(Step 5)'''&lt;br /&gt;
&lt;br /&gt;
'''Follow the topics listed in each column from left to right in order to configure an SS7 protocol stack.'''&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Configuring the MTP2 Layer &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Configuring the MTP3 Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Configuring the ISUP Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configuring the SCCP Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configuring the TCAP Layer&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP2_Configuration|Create an MTP2 Configuration]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_MTP2_Links|Create an MTP2 Link]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP3_Configuration|Create an MTP3 Configuration]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP3_Network|Create an MTP3 Network]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_SS7_Point_Codes|Create an MTP3 Point Code]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_MTP3_Linkset|Create an MTP3 Linkset]]&lt;br /&gt;
***[[Toolpack_v2.5:Creating_MTP3_Links|Create MTP3 Links]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_MTP3_Route|Create an MTP3 Route]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Stack|Create an ISUP Stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Network|Create an ISUP Network]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_User_Part|Create an ISUP User Part]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Interface|Create an ISUP Interface]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_Stack| Create an SCCP Stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_Network|Create an SCCP Network]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_Userpart|Create an SCCP Userpart]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_LSAP|Create an SCCP LSAP]]&lt;br /&gt;
***[[Toolpack_v2.5:Creating_an_SCCP_Route|Create an SCCP Route]]&lt;br /&gt;
****[[Toolpack_v2.5:Creating_an_SCCP_SSN|Create an SCCP SSN]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_GTT_Association|Create an SCCP GTT Association]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_GTT_Address_Map|Create an SCCP GTT Address Map]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_TCAP_Stack|Create a TCAP Stack]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_a_TCAP_Userpart| Create a TCAP Userpart]]&lt;br /&gt;
*[[Toolpack_v2.5:Activating_the_Configuration|Activating the Configuration]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=SIGTRAN Application Scenarios=&lt;br /&gt;
&lt;br /&gt;
Toolpack version 2.5 enables you to configure SIGTRAN and thereby extend SS7 signalling functionality to the IP network. Toolpack enables you to configure a number of SIGTRAN applications based upon your requirements. These applications are listed below as follows: &amp;lt;br&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*[[M2PA]] system. See column '''(A)''' below. In this configuration the SS7 MTP2 layer is replaced by the SIGTRAN M2PA layer which extends MTP2 signalling functionality into the IP network. This application is typically used between a Signalling Gateway and an IP Signalling Point, or between two IP Signalling Points. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[M2UA]] system. See columns '''(B)''' and '''(C)''' below. An M2UA system on a Signalling Gateway Controller interfaces with an M2UA system on a Media Gateway Controller. In this configuration, M2UA bridges the SS7 MTP2 layer of a Signalling Gateway, across an IP network, with the SS7 MTP3 layer of a Media Gateway Controller.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[IUA]] system. See column '''(D)''' below. An IUA system on a Signalling Gateway Controller interfaces with an IUA system on a Media Gateway Controller. In this configuration, IUA bridges the SS7 MTP2 layer of a Signalling Gateway, across an IP network, with the SS7 MTP3 layer of a Media Gateway Controller.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
*[[M3UA]] system on two IP signalling points. See column '''(E''') below. In this configuration the SS7 MTP2 and MTP3 layers are replaced entirely by the SIGTRAN M3UA layer. This application is typically used between two IP Signalling Points.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
*[[M3UA]] system. See columns '''(F)''' and '''(G)''' below. An M3UA system on a Signalling Gateway Process interfaces with an M3UA system on an Application Server Process. In this configuration, the MTP3 links are extended across the IP network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; '''A SIGTRAN scenario walkthrough is provided in the table columns below, to illustrate the order that must be followed when configuring SIGTRAN.''' &amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario A) &amp;lt;br&amp;gt;Configuring an M2PA System &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario B) &amp;lt;br&amp;gt;Configuring an M2UA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario C) &amp;lt;br&amp;gt;Configuring an M2UA System on a Media Gateway Controller &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario D) &amp;lt;br&amp;gt;Configuring an IUA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario E) &amp;lt;br&amp;gt;Configuring an M3UA System on IP Signalling Points &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario F) &amp;lt;br&amp;gt;Configuring an M3UA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario G) &amp;lt;br&amp;gt;Configuring an M3UA System on an Application Server&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2PA Configuration|Create an M2PA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2PA SAP|Create an M2PA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Adding M2PA Links|Add M2PA Links]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
***[[Toolpack v2.5:Creating MTP3 Links (M2PA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP2 Configuration|Create an MTP2 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP2 Links|Create MTP2 Links]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2UA Configuration|Create an M2UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA SAP|Create an M2UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA Cluster|Create an M2UA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Links|Create M2UA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Peers|Create M2UA Peers]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2UA Configuration|Create an M2UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA SAP|Create an M2UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA Cluster|Create an M2UA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Links|Create M2UA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Peers|Create M2UA Peers]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP3 Links (M2UA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the IUA Configuration|Create an IUA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an IUA SAP|Create an IUA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an IUA Cluster|Create an IUA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating IUA Links|Create IUA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating IUA Peers|Create IUA Peers]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (IPSP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (IPSP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route|Create an M3UA Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP2 Configuration|Create an MTP2 Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating MTP2 Links|Create MTP2 Links]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP3 Links (M3UA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (SGP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (SGP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route (SGP)|Create an M3UA Route]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (ASP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (ASP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route|Create an M3UA Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA ISUP Network|Create an M3UA ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring CAS R2=&lt;br /&gt;
&lt;br /&gt;
Toolpack v2.5 allows you to configure CAS R2 signaling stacks. The following table lists the basic steps that must be followed in order to configure CAS R2.&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; |&amp;lt;br&amp;gt;Configuring a CAS R2 stack&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Copy variant script|Copy variant script]] (optional)&lt;br /&gt;
*[[Toolpack v2.5:Create CAS R2 stack|Create CAS R2 stack]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_CAS_R2_NAP|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring H.248=&lt;br /&gt;
&lt;br /&gt;
The following table contains steps for configuring an H.248 media gateway control protocol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Add a Hardware Adapter &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Allocate Physical Interfaces&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Create IP Port Ranges&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configure Network Access Points (NAPs)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Adding_an_Adapter|Adding an Adapter]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create line interfaces]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create line services]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create IP port ranges]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_VoIP_Network_Access_Point_(NAP)|Allocate a VoIP network access point (NAP)]]&lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_TDM_Network_Access_Point_(NAP)|Allocate a TDM network access point (NAP)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configure the Media Gateway for H.248 mode&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 6) &amp;lt;br&amp;gt;Create an H.248 Configuration &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 7) &amp;lt;br&amp;gt;Add a New Media Gateway Controller&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 8) &amp;lt;br&amp;gt;Associate NAPs with the H.248 Configuration&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Configure the Media_Gateway_for_H248_Mode|Configure the Media Gateway for H.248 mode]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_H.248_Configuration|Create a new H.248 configuration]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Adding_a_Media_Gateway_Controller_(MGC)|Add a new media gateway controller (MGC)]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Associating_NAPs_with_an_H.248_Configuration|Associate the NAPs with the H.248 configuration]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 9) &amp;lt;br&amp;gt;Select Timeslots for TDM Terminations &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Selecting_Timeslots_for_TDM_Interfaces|Select timeslots for the TDM interfaces]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring an H.323 to SIP Converter=&lt;br /&gt;
&lt;br /&gt;
The following table contains steps for configuring NAPs that wil allow an interface between the web portal and a YATE H.323 to SIP signal converter:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | &amp;lt;br&amp;gt; Configuring an H.323 to SIP Signal Converter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
* [[Toolpack_v2.5:Creating_H.323_NAP_Columns|Create H.323 NAP columns]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create an IP port range]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Stack|Create a SIP stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Transport_Server|Create a SIP transport server]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Service_Access_Point_(SAP)|Create a service access point (SAP)]]&lt;br /&gt;
* [[Toolpack_v2.5:Creating_SIP_NAPs_(H.323)|Create SIP NAPs]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring SNMP=&lt;br /&gt;
&lt;br /&gt;
To use the Simple Network Management Protocol (SNMP)on your machine, you must first configure the '''tbSnmpAgent'''.&lt;br /&gt;
&amp;lt;br/&amp;gt;The '''tbSnmpAgent''' is a software application that interfaces between the TMedia system hardware and the [http://www.net-snmp.org NetSnmp] implementation of the SNMP that is supported by TelcoBridges.&lt;br /&gt;
By default, tbSnmpAgent is '''disabled'''. In order to use the SNMP protocol to monitor and manage your hardware, the following steps must be taken:&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* tbSnmpAgent must be '''activated'''&lt;br /&gt;
* tbSnmpAgent must be '''configured''' to suit your needs&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The aforementioned tasks can be accomplished through the [[Web Portal]]:&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
#[[Activating tbSnmpAgent|Activate tbSnmpAgent]]&lt;br /&gt;
#[[Configuring tbSnmpAgent|Configure tbSNMPAGENT to suit your needs]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Once these tasks have been completed, your TMedia platform is ready to expose system variables for polling with the Simple Network management Protocol (SNMP).&lt;br /&gt;
&lt;br /&gt;
=Status Menus=&lt;br /&gt;
&lt;br /&gt;
The Web Portal configuration tool will guide you through a number of status menus, each of which indicate the current state of a certain hardware service (assuming said service has been configured).&lt;br /&gt;
The following table contains the general conventions of the Web Portal's display '''(A)''', as well as a variety of specific status menus '''(B)'''.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (A) &amp;lt;br&amp;gt;Menus Overview &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (B) &amp;lt;br&amp;gt;Individual Menu Descriptions&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
*[[Toolpack_v2.5:Tmedia_Status_Menus|Tmedia Status Menus]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:Navigation|Navigation]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:Screen_Conventions|Status Screen Conventions]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:System|System]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Adapters_and_IP_Interfaces|Adapters and IP Interfaces]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Hosts|Hosts]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Applications|Applications]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:TDM_Lines|TDM Lines]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SCTP|SCTP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_MTP2|SS7 MTP2]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M2UA|SS7 M2UA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_IUA|SS7 IUA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M2PA|SS7 M2PA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M3UA|SS7 M3UA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_MTP3|SS7 MTP3]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_ISUP|SS7 ISUP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_SCCP|SS7 SCCP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_TCAP|SS7 TCAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:ISDN|ISDN]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:NFAS|NFAS]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:CASR2|CASR2]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SIP|SIP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Clock|Clock]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:TMS|TMS]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:NAP|NAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:H.248|H.248]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:CDR|CDR]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further information, refer to the following reading list. Please note that all guides listed below are in portable document format (*.PDF), and can be downloaded:&lt;br /&gt;
&lt;br /&gt;
*[[media:TMedia System Architecture Description.pdf|TMedia System Architecture Overview for Developers of VoIP and TDM Solutions]]&lt;br /&gt;
*[[Media:Tb640 user's guide.pdf|TB640 User's Guide]]&lt;br /&gt;
*[[media:SS7 user's guide.pdf|TelcoBridges SS7 User's Guide]]&lt;br /&gt;
*[[media:Tb640 sip user's guide.pdf|SIP User’s Guide]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Toolpack]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Web_Portal_Tutorial_Guide_v2.5</id>
		<title>Web Portal Tutorial Guide v2.5</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Web_Portal_Tutorial_Guide_v2.5"/>
				<updated>2011-10-28T14:48:44Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Configuring H.248 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=Introduction=&lt;br /&gt;
This guide is designed to provide users with a scenario-based approach to installing  [[Tmedia]] and [[Tdev]] systems, using the Web Portal configuration tool. This means that users must first go through the steps that are general to all installations, and subsequently follow the instructions that are specific to their particular application scenario (this corresponds to the type of service, and hardware system being set up).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Prerequisites==&lt;br /&gt;
This document assumes that the [[Tmedia]] or [[Tdev]] devices are installed as described in their Quick Reference Guides, and in the case of the Tmedia system communication has been established with the control network.&lt;br /&gt;
&lt;br /&gt;
(Note: Tmedia devices are shipped with the Tmedia Web Portal pre-installed, while Tdev devices require that Toolpack be installed as described in the [http://download.distribution.telcobridges.com/documentation/TMP6400_Installation_Guide.pdf TMP6400 Installation Guide].)&lt;br /&gt;
&lt;br /&gt;
Furthermore, in the case of a Tdev device and the initial configuration of the [[Toolpack]] application server, the following will have been provided:&lt;br /&gt;
*The Tdev device to which the Web Portal will first connect.&lt;br /&gt;
*The Tdev device will have been pre-configured with its physical TDM interface.&lt;br /&gt;
*The serial number of the Tdev device will have been entered into the configuration file.&lt;br /&gt;
*The application software for the Tdev device will have been pre-installed on the Toolpack application server, as described in the [http://download.distribution.telcobridges.com/documentation/TMP6400_Installation_Guide.pdf TMP6400 Installation Guide].&lt;br /&gt;
&lt;br /&gt;
This document also assumes familiarity with topics, such as [[ISDN]] signaling, [[SIP]] signaling, [[SS7]], [[CAS|CAS R2]] signaling, and [[SIGTRAN]] signaling.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Key Concepts==&lt;br /&gt;
*'''System:''' A system is defined as the complete solution that is designed for a network. If a system solution is comprised of 4 TMP6400’s and a TMS1600, then the combination of these TelcoBridges devices is termed a system.&lt;br /&gt;
*'''Hardware:''' Each TelcoBridges devices, whether it is a TMP6400, TMG3200, or TMS1600 is referred to as a hardware device or hardware adapter.&lt;br /&gt;
*'''Line Interface:''' The physical TDM module installed on the TelcoBridges device is referred to as a line interface.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== General Web Portal Applications ==&lt;br /&gt;
&lt;br /&gt;
'''''IMPORTANT!''''' The Topics covered in the following table are common to &amp;lt;u&amp;gt;all&amp;lt;/u&amp;gt; TMedia installations. Therefore, this section should be consulted before moving on to any other. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; '''Topics covered here:''' &lt;br /&gt;
&lt;br /&gt;
*The basic knowledge needed to properly navigate through the Web Portal '''(A)'''. &lt;br /&gt;
*The fundamentals of user account management and permission masks '''(B)'''. &lt;br /&gt;
*The initial steps required for first starting the Web Portal, and verifying that it is functioning properly '''(C)'''. &lt;br /&gt;
*The process involved in backing up your database for the first time '''(D)'''. &lt;br /&gt;
*The process involved in first configuring your IP interfaces '''(E)'''.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic A) &amp;lt;br&amp;gt;Web Portal Basics &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic B) &amp;lt;br&amp;gt;Log-on and User Access Levels &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic C) &amp;lt;br&amp;gt;Application Start-up and Verification &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic D) &amp;lt;br&amp;gt;Database Backup&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Navigating the Web Portal|Navigating the Web Portal]] &lt;br /&gt;
*[[Typographic conventions|Typographic Conventions]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Connecting to the Web Server and logging on to the web portal|Connect to the web server and log on to the Web Portal]] &lt;br /&gt;
*[[Toolpack:User access|User Access]] &lt;br /&gt;
**[[Toolpack v2.5:Viewing the User List|Viewing the User List]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a New User|Creating a New User]] &lt;br /&gt;
**[[Toolpack v2.5:Deleting a User|Deleting a User]] &lt;br /&gt;
**[[Toolpack v2.5:Logging Off Toolpack|Logging Off]] &lt;br /&gt;
*[https://forums.telcobridges.com/viewtopic.php?f=12&amp;amp;t=248&amp;amp;p=1101&amp;amp;hilit=privilege#p1101 User privilege level]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Viewing the List of Installed Applications|Viewing the List of Installed Applications]] &lt;br /&gt;
*[[Toolpack v2.5:Starting an Application|Starting an Application]] &lt;br /&gt;
*[[Toolpack:Verifying that an Application is Operating|Verifying that an Application is Operating]] &lt;br /&gt;
**[[Toolpack v2.5:Verifying the Application Path|Verifying the Application Path]] &lt;br /&gt;
*[[Toolpack v2.5:Activating the Configuration|Activating the Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Status Menus:Applications|Verifying status]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Database Backup|Carrying out a First Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Downloading a Database Backup|Downloading a Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Uploading a Database Backup|Uploading a Database Backup]]&lt;br /&gt;
*[[Toolpack v2.5:Restoring a Database Backup|Restoring a Database Backup]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: none repeat scroll 0% 0% rgb(239, 239, 239); -moz-background-inline-policy: continuous;&amp;quot; | (Topic E) &amp;lt;br&amp;gt;Configure IP Interfaces&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Configuring IP Interfaces|Configure IP Interfaces]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=ISDN-SIP Gateway Configuration=&lt;br /&gt;
&lt;br /&gt;
The following tables contain a typical configuration scenario for an [[ISDN]] to [[SIP]] gateway. This type of installation allows for the transfer of information from traditional [[ISDN]] signaling to [[SIP]] protocol for [[VoIP]] applications. Please follow each step one after another as these are listed in logical order.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'''The steps are as follows:'''&lt;br /&gt;
&lt;br /&gt;
*1) Log On and Create a New Configuration&lt;br /&gt;
*2) Allocate Physical Interfaces&lt;br /&gt;
*3) Configure ISDN-PRI Signaling&lt;br /&gt;
*4) Configure Clocking Source&lt;br /&gt;
*5) Configure SIP Signaling&lt;br /&gt;
*6) Configure Codecs and Tone Detection&lt;br /&gt;
*7) Configure Network Access Points (NAPs)&lt;br /&gt;
*8) Create Call Routing Rules&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;'''IMPORTANT!'''&amp;lt;/b&amp;gt; After completing the setup process, remember to '''activate the configuration''', as outlined in the [[Web_Portal_Tutorial_Guide_v2.5#General_Web_Portal_Applications|General Web Portal Applications section]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Log On and Create a New Configuration&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Allocate Physical Interfaces&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Configure ISDN-PRI Signaling&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configure Clocking Source&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Connecting_to_the_Web_Server_and logging on to the web portal|Connect to the web server and log on to the Web Portal]]&lt;br /&gt;
*[[Toolpack_v2.5:Copying_the_Default_Configuration|Copy the default configuration]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create a new line interface]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create a new line service]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Configuring_an_ISDN_Stack|Configure an ISDN stack]]&lt;br /&gt;
OR&amp;lt;br/&amp;gt;&lt;br /&gt;
*[[Configure NFAS]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Defining_a_Clocking_Source|Define a clocking source]] &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configure SIP Signaling&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 6) &amp;lt;br&amp;gt;Configure Codecs and Tone Detection&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 7) &amp;lt;br&amp;gt;Configure Network Access Points (NAPs)&lt;br /&gt;
&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 8) &amp;lt;br&amp;gt;Create Call Routing Rules&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create an IP port range]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Stack|Create a SIP stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Transport_Server|Create a SIP transport server]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Service_Access_Point_(SAP)|Create a service access point (SAP)]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Accessing_Codec_and_Tone_Detection_Profiles_and_Validating_Settings|Access profiles and validate settings]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Allocating_an_ISDN_Network_Access_Point_(NAP)|Allocate an ISDN NAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_SIP_Network_Access_Point_(NAP)|Allocate a SIP NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_First_Call_Route|Create a first call route]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring SS7=&lt;br /&gt;
&lt;br /&gt;
The following table contains information on configuring the [[SS7]] signaling protocol.&lt;br /&gt;
The various control layers of the [[SS7]] protocol are listed individually in each column. These layers are:&lt;br /&gt;
&lt;br /&gt;
* [[MTP2_Layer|MTP2]] layer '''(Step 1)'''&lt;br /&gt;
* [[MTP3_Layer|MTP3]] layer '''(Step 2)'''&lt;br /&gt;
* [[ISUP]] layer '''(Step 3)'''&lt;br /&gt;
* [[SCCP]] layer '''(Step 4)'''&lt;br /&gt;
* [[TCAP]] layer '''(Step 5)'''&lt;br /&gt;
&lt;br /&gt;
'''Follow the topics listed in each column from left to right in order to configure an SS7 protocol stack.'''&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Configuring the MTP2 Layer &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Configuring the MTP3 Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Configuring the ISUP Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configuring the SCCP Layer&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configuring the TCAP Layer&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP2_Configuration|Create an MTP2 Configuration]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_MTP2_Links|Create an MTP2 Link]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP3_Configuration|Create an MTP3 Configuration]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_MTP3_Network|Create an MTP3 Network]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_SS7_Point_Codes|Create an MTP3 Point Code]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_MTP3_Linkset|Create an MTP3 Linkset]]&lt;br /&gt;
***[[Toolpack_v2.5:Creating_MTP3_Links|Create MTP3 Links]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_MTP3_Route|Create an MTP3 Route]] &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Stack|Create an ISUP Stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Network|Create an ISUP Network]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_User_Part|Create an ISUP User Part]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_ISUP_Interface|Create an ISUP Interface]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_Stack| Create an SCCP Stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_Network|Create an SCCP Network]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_Userpart|Create an SCCP Userpart]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_LSAP|Create an SCCP LSAP]]&lt;br /&gt;
***[[Toolpack_v2.5:Creating_an_SCCP_Route|Create an SCCP Route]]&lt;br /&gt;
****[[Toolpack_v2.5:Creating_an_SCCP_SSN|Create an SCCP SSN]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_SCCP_GTT_Association|Create an SCCP GTT Association]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_an_SCCP_GTT_Address_Map|Create an SCCP GTT Address Map]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_TCAP_Stack|Create a TCAP Stack]]&lt;br /&gt;
**[[Toolpack_v2.5:Creating_a_TCAP_Userpart| Create a TCAP Userpart]]&lt;br /&gt;
*[[Toolpack_v2.5:Activating_the_Configuration|Activating the Configuration]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=SIGTRAN Application Scenarios=&lt;br /&gt;
&lt;br /&gt;
Toolpack version 2.5 enables you to configure SIGTRAN and thereby extend SS7 signalling functionality to the IP network. Toolpack enables you to configure a number of SIGTRAN applications based upon your requirements. These applications are listed below as follows: &amp;lt;br&amp;gt;&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
*[[M2PA]] system. See column '''(A)''' below. In this configuration the SS7 MTP2 layer is replaced by the SIGTRAN M2PA layer which extends MTP2 signalling functionality into the IP network. This application is typically used between a Signalling Gateway and an IP Signalling Point, or between two IP Signalling Points. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[M2UA]] system. See columns '''(B)''' and '''(C)''' below. An M2UA system on a Signalling Gateway Controller interfaces with an M2UA system on a Media Gateway Controller. In this configuration, M2UA bridges the SS7 MTP2 layer of a Signalling Gateway, across an IP network, with the SS7 MTP3 layer of a Media Gateway Controller.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*[[IUA]] system. See column '''(D)''' below. An IUA system on a Signalling Gateway Controller interfaces with an IUA system on a Media Gateway Controller. In this configuration, IUA bridges the SS7 MTP2 layer of a Signalling Gateway, across an IP network, with the SS7 MTP3 layer of a Media Gateway Controller.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
*[[M3UA]] system on two IP signalling points. See column '''(E''') below. In this configuration the SS7 MTP2 and MTP3 layers are replaced entirely by the SIGTRAN M3UA layer. This application is typically used between two IP Signalling Points.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
*[[M3UA]] system. See columns '''(F)''' and '''(G)''' below. An M3UA system on a Signalling Gateway Process interfaces with an M3UA system on an Application Server Process. In this configuration, the MTP3 links are extended across the IP network.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; '''A SIGTRAN scenario walkthrough is provided in the table columns below, to illustrate the order that must be followed when configuring SIGTRAN.''' &amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario A) &amp;lt;br&amp;gt;Configuring an M2PA System &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario B) &amp;lt;br&amp;gt;Configuring an M2UA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario C) &amp;lt;br&amp;gt;Configuring an M2UA System on a Media Gateway Controller &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario D) &amp;lt;br&amp;gt;Configuring an IUA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario E) &amp;lt;br&amp;gt;Configuring an M3UA System on IP Signalling Points &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario F) &amp;lt;br&amp;gt;Configuring an M3UA System on a Signalling Gateway &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Scenario G) &amp;lt;br&amp;gt;Configuring an M3UA System on an Application Server&lt;br /&gt;
|-&lt;br /&gt;
| &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2PA Configuration|Create an M2PA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2PA SAP|Create an M2PA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Adding M2PA Links|Add M2PA Links]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
***[[Toolpack v2.5:Creating MTP3 Links (M2PA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP2 Configuration|Create an MTP2 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP2 Links|Create MTP2 Links]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2UA Configuration|Create an M2UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA SAP|Create an M2UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA Cluster|Create an M2UA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Links|Create M2UA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Peers|Create M2UA Peers]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the M2UA Configuration|Create an M2UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA SAP|Create an M2UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M2UA Cluster|Create an M2UA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Links|Create M2UA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating M2UA Peers|Create M2UA Peers]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP3 Links (M2UA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating the IUA Configuration|Create an IUA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an IUA SAP|Create an IUA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an IUA Cluster|Create an IUA Cluster]] &lt;br /&gt;
**[[Toolpack v2.5:Creating IUA Links|Create IUA Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating IUA Peers|Create IUA Peers]]&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (IPSP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (IPSP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route|Create an M3UA Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Network|Create an ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Creating a Line Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP2 Configuration|Create an MTP2 Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating MTP2 Links|Create MTP2 Links]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an MTP3 Configuration|Create an MTP3 Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Network|Create an MTP3 Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Linkset|Create an MTP3 Linkset]] &lt;br /&gt;
**[[Toolpack v2.5:Creating MTP3 Links (M3UA)|Create MTP3 Links]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an MTP3 Route|Create an MTP3 Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (SGP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (SGP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route (SGP)|Create an M3UA Route]]&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack v2.5:Editing the SCTP Configuration|Edit the SCTP Configuration]] &lt;br /&gt;
*[[Toolpack v2.5:Creating SS7 Point Codes|Create SS7 Point Codes]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an M3UA Configuration (ASP)|Create an M3UA Configuration]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA SAP|Create an M3UA SAP]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Network|Create an M3UA Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA User Part|Create an M3UA User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Signalling Process (ASP)|Create an M3UA Peer Signalling Process]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Peer Server|Create an M3UA Peer Server]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA Route|Create an M3UA Route]] &lt;br /&gt;
*[[Toolpack v2.5:Creating an ISUP Stack|Create an ISUP Stack]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an M3UA ISUP Network|Create an M3UA ISUP Network]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP User Part|Create an ISUP User Part]] &lt;br /&gt;
**[[Toolpack v2.5:Creating an ISUP Interface|Create an ISUP Interface]] &lt;br /&gt;
***[[Toolpack v2.5:Creating ISUP CIC Groups|Create ISUP CIC Groups]] &lt;br /&gt;
**[[Toolpack v2.5:Creating a NAP (SIGTRAN)|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring CAS R2=&lt;br /&gt;
&lt;br /&gt;
Toolpack v2.5 allows you to configure CAS R2 signaling stacks. The following table lists the basic steps that must be followed in order to configure CAS R2.&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; |&amp;lt;br&amp;gt;Configuring a CAS R2 stack&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack v2.5:Adding an Adapter|Adding an Adapter]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create Line Interfaces]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create Line services]] &lt;br /&gt;
*[[Toolpack v2.5:Copy variant script|Copy variant script]] (optional)&lt;br /&gt;
*[[Toolpack v2.5:Create CAS R2 stack|Create CAS R2 stack]] &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_CAS_R2_NAP|Create a NAP]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring H.248=&lt;br /&gt;
&lt;br /&gt;
The following table contains steps for configuring an H.248 media gateway control protocol&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 1) &amp;lt;br&amp;gt;Add a Hardware Adapter &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 2) &amp;lt;br&amp;gt;Allocate Physical Interfaces&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 3) &amp;lt;br&amp;gt;Create IP Port Ranges&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 4) &amp;lt;br&amp;gt;Configure Network Access Points (NAPs)&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Adding_an_Adapter|Adding an Adapter]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Interface|Create line interfaces]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Line_Service|Create line services]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create IP port ranges]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_VoIP_Network_Access_Point_(NAP)|Allocate a VoIP network access point (NAP)]]&lt;br /&gt;
*[[Toolpack_v2.5:Allocating_a_TDM_Network_Access_Point_(NAP)|Allocate a TDM network access point (NAP)]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 5) &amp;lt;br&amp;gt;Configure the Media Gateway for H.248 mode&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 6) &amp;lt;br&amp;gt;Create an H.248 Configuration &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 7) &amp;lt;br&amp;gt;Add a New Media Gateway Controller&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 8) &amp;lt;br&amp;gt;Associate NAPs with the H.248 Configuration&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_H.248_Configuration|Create a new H.248 configuration]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Configure the Media_Gateway_for_H248_Mode|Configure the Media Gateway for H.248 mode]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
*[[Toolpack_v2.5:Adding_a_Media_Gateway_Controller_(MGC)|Add a new media gateway controller (MGC)]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Associating_NAPs_with_an_H.248_Configuration|Associate the NAPs with the H.248 configuration]]&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (Step 9) &amp;lt;br&amp;gt;Select Timeslots for TDM Terminations &lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
*[[Toolpack_v2.5:Selecting_Timeslots_for_TDM_Interfaces|Select timeslots for the TDM interfaces]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring an H.323 to SIP Converter=&lt;br /&gt;
&lt;br /&gt;
The following table contains steps for configuring NAPs that wil allow an interface between the web portal and a YATE H.323 to SIP signal converter:&lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | &amp;lt;br&amp;gt; Configuring an H.323 to SIP Signal Converter&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
* [[Toolpack_v2.5:Creating_H.323_NAP_Columns|Create H.323 NAP columns]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_an_IP_Port_Range|Create an IP port range]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Stack|Create a SIP stack]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_SIP_Transport_Server|Create a SIP transport server]]&lt;br /&gt;
*[[Toolpack_v2.5:Creating_a_Service_Access_Point_(SAP)|Create a service access point (SAP)]]&lt;br /&gt;
* [[Toolpack_v2.5:Creating_SIP_NAPs_(H.323)|Create SIP NAPs]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Configuring SNMP=&lt;br /&gt;
&lt;br /&gt;
To use the Simple Network Management Protocol (SNMP)on your machine, you must first configure the '''tbSnmpAgent'''.&lt;br /&gt;
&amp;lt;br/&amp;gt;The '''tbSnmpAgent''' is a software application that interfaces between the TMedia system hardware and the [http://www.net-snmp.org NetSnmp] implementation of the SNMP that is supported by TelcoBridges.&lt;br /&gt;
By default, tbSnmpAgent is '''disabled'''. In order to use the SNMP protocol to monitor and manage your hardware, the following steps must be taken:&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
* tbSnmpAgent must be '''activated'''&lt;br /&gt;
* tbSnmpAgent must be '''configured''' to suit your needs&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
The aforementioned tasks can be accomplished through the [[Web Portal]]:&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
#[[Activating tbSnmpAgent|Activate tbSnmpAgent]]&lt;br /&gt;
#[[Configuring tbSnmpAgent|Configure tbSNMPAGENT to suit your needs]]&lt;br /&gt;
&amp;lt;br/&amp;gt;&lt;br /&gt;
Once these tasks have been completed, your TMedia platform is ready to expose system variables for polling with the Simple Network management Protocol (SNMP).&lt;br /&gt;
&lt;br /&gt;
=Status Menus=&lt;br /&gt;
&lt;br /&gt;
The Web Portal configuration tool will guide you through a number of status menus, each of which indicate the current state of a certain hardware service (assuming said service has been configured).&lt;br /&gt;
The following table contains the general conventions of the Web Portal's display '''(A)''', as well as a variety of specific status menus '''(B)'''.&lt;br /&gt;
 &lt;br /&gt;
&lt;br /&gt;
{| cellpadding=&amp;quot;5&amp;quot; border=&amp;quot;1&amp;quot; class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (A) &amp;lt;br&amp;gt;Menus Overview &lt;br /&gt;
! width=&amp;quot;200&amp;quot; style=&amp;quot;background: rgb(239, 239, 239) none repeat scroll 0% 0%; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;&amp;quot; | (B) &amp;lt;br&amp;gt;Individual Menu Descriptions&lt;br /&gt;
&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; |&lt;br /&gt;
&lt;br /&gt;
*[[Toolpack_v2.5:Tmedia_Status_Menus|Tmedia Status Menus]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:Navigation|Navigation]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:Screen_Conventions|Status Screen Conventions]]&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:System|System]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Adapters_and_IP_Interfaces|Adapters and IP Interfaces]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Hosts|Hosts]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Applications|Applications]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:TDM_Lines|TDM Lines]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SCTP|SCTP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_MTP2|SS7 MTP2]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M2UA|SS7 M2UA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_IUA|SS7 IUA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M2PA|SS7 M2PA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_M3UA|SS7 M3UA]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_MTP3|SS7 MTP3]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_ISUP|SS7 ISUP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_SCCP|SS7 SCCP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SS7_TCAP|SS7 TCAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:ISDN|ISDN]]&lt;br /&gt;
**[[Toolpack_v2.5:Status_Menus:NFAS|NFAS]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:CASR2|CASR2]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:SIP|SIP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:Clock|Clock]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:TMS|TMS]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:NAP|NAP]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:H.248|H.248]]&lt;br /&gt;
*[[Toolpack_v2.5:Status_Menus:CDR|CDR]]&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=Further Reading=&lt;br /&gt;
For further information, refer to the following reading list. Please note that all guides listed below are in portable document format (*.PDF), and can be downloaded:&lt;br /&gt;
&lt;br /&gt;
*[[media:TMedia System Architecture Description.pdf|TMedia System Architecture Overview for Developers of VoIP and TDM Solutions]]&lt;br /&gt;
*[[Media:Tb640 user's guide.pdf|TB640 User's Guide]]&lt;br /&gt;
*[[media:SS7 user's guide.pdf|TelcoBridges SS7 User's Guide]]&lt;br /&gt;
*[[media:Tb640 sip user's guide.pdf|SIP User’s Guide]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Toolpack]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Tone_definitions</id>
		<title>Tone definitions</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Tone_definitions"/>
				<updated>2011-10-07T21:23:46Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;=== Tone definitions  ===&lt;br /&gt;
&lt;br /&gt;
It is possible through the [[Toolpack]] [[Web Portal]] to specify the parameters of ringing, busy, congestion (or fast busy) and warning call progress tones. These settings are available in &lt;br /&gt;
&amp;lt;pre&amp;gt;Profiles -&amp;amp;gt; Tone Profile Params &amp;lt;/pre&amp;gt; &lt;br /&gt;
The tones are described using a programmable string of characters as defined in the [[H.248]] Dynamic Tone Definition Package. To learn more about tone description strings, see the [[CAF: Working With Call Legs#Play_Tone_with_Signal_Id_String|section]] related to this subject. &lt;br /&gt;
&lt;br /&gt;
=== Examples of Call Progress tones  ===&lt;br /&gt;
&lt;br /&gt;
The following table contains a few call progress tone definition strings that can be used to replace the default ones in the Toolpack Web Portal. &lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! &amp;lt;br&amp;gt; &lt;br /&gt;
! Ring &lt;br /&gt;
! Busy &lt;br /&gt;
! Congestion &lt;br /&gt;
! Warning&lt;br /&gt;
|-&lt;br /&gt;
! Australia&amp;lt;br&amp;gt; &lt;br /&gt;
| ((((#400)+(#450)),400),(#0,200),(((#400)+(#450)),400),(#0,2000))*0 &amp;lt;br&amp;gt; &lt;br /&gt;
| ((#425,375),(#0,375))*0&amp;lt;br&amp;gt; &lt;br /&gt;
| ((#425,375),(#0,375))*0&amp;lt;br&amp;gt; &lt;br /&gt;
| ((#900),500) &amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Bangladesh&amp;lt;br&amp;gt; &lt;br /&gt;
| ((#425,1000),(#0,4000))*0&amp;lt;br&amp;gt; &lt;br /&gt;
| ((#450,200),(#0,300),(#450,700),(#0,800))*0 &amp;lt;br&amp;gt; &lt;br /&gt;
| ((#425,250),(#0,250))*0 &amp;lt;br&amp;gt; &lt;br /&gt;
| ((#450,200),(#0,20),(#450,200),(#0,140))*0 &amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! Brazil &lt;br /&gt;
| ((#425,1000),(#0,4000))*0 &lt;br /&gt;
| ((#425,250),(#0,250))*0 &lt;br /&gt;
| ((#425,750),(#0,250),(#425,250),(#0,250))*0 &lt;br /&gt;
| ''unused''&lt;br /&gt;
|-&lt;br /&gt;
! China &lt;br /&gt;
| ((#450,1000),(#0,4000))*0 &lt;br /&gt;
| ((#450,350),(#0,350))*0 &lt;br /&gt;
| ((#450,700),(#0,700))*0 &lt;br /&gt;
| ''unused''&lt;br /&gt;
|-&lt;br /&gt;
! France &lt;br /&gt;
| ((#440,1500),(#0,3500))*0 &lt;br /&gt;
| ((#450,500),(#0,500))*0 &lt;br /&gt;
| ''unused'' &lt;br /&gt;
| ''unused''&lt;br /&gt;
|-&lt;br /&gt;
! Germany &lt;br /&gt;
| ((#425,1000),(#0,4000))*0 &lt;br /&gt;
| ((#425,480),(#0,480))*0 &lt;br /&gt;
| ((#425,240),(#0,240))*0 &lt;br /&gt;
| ((#425,240),(#0,240),(#425,240),(#0,1280))*0&lt;br /&gt;
|-&lt;br /&gt;
! Hong Kong &lt;br /&gt;
| ((((#440)+(#480)),400),(#0,200),(((#440)+(#480)),400),(#0,3000))*0 &lt;br /&gt;
| ((((#480)+(#620)),500),(#0,500))*0 &lt;br /&gt;
| ((((#480)+(#620)),250),(#0,250))*0 &lt;br /&gt;
| ''unused''&lt;br /&gt;
|-&lt;br /&gt;
! Netherlands&amp;lt;br&amp;gt;&lt;br /&gt;
| ((#425,1000),(#0,4000))*0 &amp;lt;br&amp;gt;&lt;br /&gt;
| ((#425,500),(#0,500))*0 &amp;lt;br&amp;gt;&lt;br /&gt;
| ((#425,250),(#0,250))*0 &amp;lt;br&amp;gt;&lt;br /&gt;
| ''unused''&amp;lt;br&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
! North America &lt;br /&gt;
| ((((#440)+(#480)),2000),(#0,4000))*0 &lt;br /&gt;
| ((((#480)+(#620)),500),(#0,500))*0 &lt;br /&gt;
| ((((#480)+(#620)),250),(#0,250))*0 &lt;br /&gt;
| ((#1400),500)&lt;br /&gt;
|-&lt;br /&gt;
! Spain &lt;br /&gt;
| ((#425,1500),(#0,3000))*0 &lt;br /&gt;
| ((#425,200),(#0,200))*0 &lt;br /&gt;
| ((#425,200),(#0,200),(#425,200),(#0,200),(#425,200),(#0,600))*0 &lt;br /&gt;
| (((#1400),400),(#0,5000))*0&lt;br /&gt;
|-&lt;br /&gt;
! United Kingdom &lt;br /&gt;
| ((((#400)+(#450)),400),(#0,200),(((#400)+(#450)),400),(#0,2000))*0 &lt;br /&gt;
| ((#400,375),(#0,375))*0 &lt;br /&gt;
| ((#400,400),(#0,350),(#400,225),(#0,525))*0 &lt;br /&gt;
| ''unused''&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! The Moon... &lt;br /&gt;
| ((#262,2000),(#391,2000),(#523,4000),(((#659)+(#523)),250),(((#622)+(#523)),3750),(#262,400),(#196,400),(#262,400),(#196,400),(#262,400),(#196,400),(#262,400),(#196,400),(#262,420),(#196,460),(#262,540),(#196,620))*0&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== Playing and collecting tones  ===&lt;br /&gt;
&lt;br /&gt;
To learn how to play these tones using the [[CAF: Working With Call Legs|Call Leg API]], refer to the [[CAF: Working With Call Legs#Playing_and_Collecting_Tones|Playing and Collecting Tones section]]. &lt;br /&gt;
&lt;br /&gt;
For example, to play the '''ringing''' tone, one could pass either directly &amp;lt;code&amp;gt;((((#440)+(#480)),2000),(#0,4000))*0&amp;lt;/code&amp;gt; or &amp;lt;code&amp;gt;cg/rt&amp;lt;/code&amp;gt; to the '''AddToneString()''' function. The &amp;lt;code&amp;gt;cg/rt&amp;lt;/code&amp;gt; string refers to the current Tone Profile Params ringing tone setting from the Web Portal. &lt;br /&gt;
&lt;br /&gt;
=== Tone volume  ===&lt;br /&gt;
&lt;br /&gt;
It is possible to change the ring tone volume. According to the syntax, you need to specify the desired volume after the tone duration. Here is an example:&lt;br /&gt;
((((#440)+(#480)),2000,'''-15'''),(#0,4000))*0&lt;br /&gt;
&lt;br /&gt;
The possible values are: -19, -15, -10, -5 and 0 dB.&lt;br /&gt;
&lt;br /&gt;
=== Available tones  ===&lt;br /&gt;
&lt;br /&gt;
Below is a comprehensive list of all the tone strings that can be passed to the '''AddToneString()''' function. &lt;br /&gt;
&lt;br /&gt;
{|&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
{| cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ '''Tone generation''' &lt;br /&gt;
|-&lt;br /&gt;
! Package &lt;br /&gt;
! Signal &lt;br /&gt;
! String&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;16&amp;quot; | Basic DTMF generation &lt;br /&gt;
| 0 &lt;br /&gt;
| dg/d0&lt;br /&gt;
|-&lt;br /&gt;
| 1 &lt;br /&gt;
| dg/d1&lt;br /&gt;
|-&lt;br /&gt;
| 2 &lt;br /&gt;
| dg/d2&lt;br /&gt;
|-&lt;br /&gt;
| 3 &lt;br /&gt;
| dg/d3&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| dg/d4&lt;br /&gt;
|-&lt;br /&gt;
| 5 &lt;br /&gt;
| dg/d5&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| dg/d6&lt;br /&gt;
|-&lt;br /&gt;
| 7 &lt;br /&gt;
| dg/d7&lt;br /&gt;
|-&lt;br /&gt;
| 8 &lt;br /&gt;
| dg/d8&lt;br /&gt;
|-&lt;br /&gt;
| 9 &lt;br /&gt;
| dg/d9&lt;br /&gt;
|-&lt;br /&gt;
| * &lt;br /&gt;
| dg/ds&lt;br /&gt;
|-&lt;br /&gt;
| # &lt;br /&gt;
| dg/do&lt;br /&gt;
|-&lt;br /&gt;
| A &lt;br /&gt;
| dg/da&lt;br /&gt;
|-&lt;br /&gt;
| B &lt;br /&gt;
| dg/db&lt;br /&gt;
|-&lt;br /&gt;
| C &lt;br /&gt;
| dg/dc&lt;br /&gt;
|-&lt;br /&gt;
| D &lt;br /&gt;
| dg/dd&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;4&amp;quot; | Call Progress generation &lt;br /&gt;
| Ring &lt;br /&gt;
| cg/rt&lt;br /&gt;
|-&lt;br /&gt;
| Busy &lt;br /&gt;
| cg/bt&lt;br /&gt;
|-&lt;br /&gt;
| Congestion &lt;br /&gt;
| cg/ct&lt;br /&gt;
|-&lt;br /&gt;
| Warning &lt;br /&gt;
| cg/wt&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;12&amp;quot; | MF tone generation &lt;br /&gt;
| 0 &lt;br /&gt;
| mfg/mf0&lt;br /&gt;
|-&lt;br /&gt;
| 1 &lt;br /&gt;
| mfg/mf1&lt;br /&gt;
|-&lt;br /&gt;
| 2 &lt;br /&gt;
| mfg/mf2&lt;br /&gt;
|-&lt;br /&gt;
| 3 &lt;br /&gt;
| mfg/mf3&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| mfg/mf4&lt;br /&gt;
|-&lt;br /&gt;
| 5 &lt;br /&gt;
| mfg/mf5&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| mfg/mf6&lt;br /&gt;
|-&lt;br /&gt;
| 7 &lt;br /&gt;
| mfg/mf7&lt;br /&gt;
|-&lt;br /&gt;
| 8 &lt;br /&gt;
| mfg/mf8&lt;br /&gt;
|-&lt;br /&gt;
| 9 &lt;br /&gt;
| mfg/mf9&lt;br /&gt;
|-&lt;br /&gt;
| KP &lt;br /&gt;
| mfg/mfa&lt;br /&gt;
|-&lt;br /&gt;
| ST &lt;br /&gt;
| mfg/mfe&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;2&amp;quot; | Telcofax &lt;br /&gt;
| CNG &lt;br /&gt;
| telcofax/cng&lt;br /&gt;
|-&lt;br /&gt;
| g164 &lt;br /&gt;
| telcofax/g164&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; | &lt;br /&gt;
{| cellspacing=&amp;quot;1&amp;quot; cellpadding=&amp;quot;2&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|+ '''Tone detection''' &lt;br /&gt;
|-&lt;br /&gt;
! Package &lt;br /&gt;
! Signal &lt;br /&gt;
! String&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;16&amp;quot; | Basic DTMF detection &lt;br /&gt;
| 0 &lt;br /&gt;
| dd/d0&lt;br /&gt;
|-&lt;br /&gt;
| 1 &lt;br /&gt;
| dd/d1&lt;br /&gt;
|-&lt;br /&gt;
| 2 &lt;br /&gt;
| dd/d2&lt;br /&gt;
|-&lt;br /&gt;
| 3 &lt;br /&gt;
| dd/d3&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| dd/d4&lt;br /&gt;
|-&lt;br /&gt;
| 5 &lt;br /&gt;
| dd/d5&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| dd/d6&lt;br /&gt;
|-&lt;br /&gt;
| 7 &lt;br /&gt;
| dd/d7&lt;br /&gt;
|-&lt;br /&gt;
| 8 &lt;br /&gt;
| dd/d8&lt;br /&gt;
|-&lt;br /&gt;
| 9 &lt;br /&gt;
| dd/d9&lt;br /&gt;
|-&lt;br /&gt;
| * &lt;br /&gt;
| dd/ds&lt;br /&gt;
|-&lt;br /&gt;
| # &lt;br /&gt;
| dd/do&lt;br /&gt;
|-&lt;br /&gt;
| A &lt;br /&gt;
| dd/da&lt;br /&gt;
|-&lt;br /&gt;
| B &lt;br /&gt;
| dd/db&lt;br /&gt;
|-&lt;br /&gt;
| C &lt;br /&gt;
| dd/dc&lt;br /&gt;
|-&lt;br /&gt;
| D &lt;br /&gt;
| dd/dd&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;12&amp;quot; | MF tone generation &lt;br /&gt;
| 0 &lt;br /&gt;
| mfd/mf0&lt;br /&gt;
|-&lt;br /&gt;
| 1 &lt;br /&gt;
| mfd/mf1&lt;br /&gt;
|-&lt;br /&gt;
| 2 &lt;br /&gt;
| mfd/mf2&lt;br /&gt;
|-&lt;br /&gt;
| 3 &lt;br /&gt;
| mfd/mf3&lt;br /&gt;
|-&lt;br /&gt;
| 4 &lt;br /&gt;
| mfd/mf4&lt;br /&gt;
|-&lt;br /&gt;
| 5 &lt;br /&gt;
| mfd/mf5&lt;br /&gt;
|-&lt;br /&gt;
| 6 &lt;br /&gt;
| mfd/mf6&lt;br /&gt;
|-&lt;br /&gt;
| 7 &lt;br /&gt;
| mfd/mf7&lt;br /&gt;
|-&lt;br /&gt;
| 8 &lt;br /&gt;
| mfd/mf8&lt;br /&gt;
|-&lt;br /&gt;
| 9 &lt;br /&gt;
| mfd/mf9&lt;br /&gt;
|-&lt;br /&gt;
| KP &lt;br /&gt;
| mfd/mfa&lt;br /&gt;
|-&lt;br /&gt;
| ST &lt;br /&gt;
| mfd/mfe&lt;br /&gt;
|-&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; rowspan=&amp;quot;3&amp;quot; | Telcofax &lt;br /&gt;
| CNG &lt;br /&gt;
| telcofax/cng&lt;br /&gt;
|-&lt;br /&gt;
| g164 &lt;br /&gt;
| telcofax/g164&lt;br /&gt;
|-&lt;br /&gt;
| g165 &lt;br /&gt;
| telcofax/g165&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
=== References  ===&lt;br /&gt;
&lt;br /&gt;
*[http://www.itu.int/publ/T-SP-E.180-2003/en Various tones used in national networks] &lt;br /&gt;
*[http://www.itu.int/rec/T-REC-H.248.6-200011-I/en H.248 Gateway Control Protocol Dynamic Tone Definition Package] &lt;br /&gt;
*[http://www.itu.int/rec/T-REC-H.248.1-200509-I/en H.248 Gateway Control Protocol] section E.7 (Call Progress Tone Definitions Package)&lt;br /&gt;
&lt;br /&gt;
[[Category:Needs_revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace</id>
		<title>Toolpack Debug Application:Tbsigtrace</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace"/>
				<updated>2011-06-23T17:29:17Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Examples */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tbsigtrace is a debug tool that is use to collect protocol messages. It can trace SS7, ISDN, SIP, Sigtran and CAS messages and put it in a [http://www.wireshark.org wireshark] format.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Application Location&amp;lt;br&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The binary is located in the [InstallDir]/[PackageVersion]/bin/release/[Platform]/ &lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, TMG unit (PPC 32bits) &lt;br /&gt;
&lt;br /&gt;
 /lib/tb/toolpack/pkg/2.5.55/bin/release/ppc-linux/tbsigtrace&lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, CentOS 64 bits system &lt;br /&gt;
&lt;br /&gt;
 /lib/tb/toolpack/pkg/2.5.55/bin/release/x86_64-linux64/tbsigtrace&lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, Windows system &lt;br /&gt;
&lt;br /&gt;
 C:\TelcoBridges\toolpack\pkg\2.5.55\bin\release\i586-win32\tbsigtrace.exe&lt;br /&gt;
&lt;br /&gt;
== How to use it  ==&lt;br /&gt;
&lt;br /&gt;
=== Command line  ===&lt;br /&gt;
&lt;br /&gt;
Options available: &lt;br /&gt;
&lt;br /&gt;
:-d Daemon mode &lt;br /&gt;
:-name XYZ Application name &lt;br /&gt;
:-db Not used &lt;br /&gt;
:-c XYZ Configuration file to load &lt;br /&gt;
:-gw XYZ [[System Id|SystemId]] (i.e. 12358) &lt;br /&gt;
:-adapter TBXYZ Adapter name to connect or &amp;quot;all&amp;quot; to connect to all adapter in the system &lt;br /&gt;
:-ss7 Default ss7 trace activation &lt;br /&gt;
:-isdn Default isdn trace activation &lt;br /&gt;
:-ip Default ip trace activation (sip, sigtran and iua) &lt;br /&gt;
:-h248 Default h248 trace activation &lt;br /&gt;
:-lapd Default lapd trace activation&lt;br /&gt;
:-cap CAP format enabled &lt;br /&gt;
&lt;br /&gt;
==== Examples  ====&lt;br /&gt;
&lt;br /&gt;
This will gather all ss7 links from one blade and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -ss7 -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all isdn links from one blade and put them in several files &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -isdn -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all sip traces and put them in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -sip -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; In release 2.4 This will gather all sip and sigtran traces and put them in a single cap file for all adapters in the system &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter all -ip -cap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will gather all h248 messages on the system and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -h248 -cap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will gather all IUA (ip and tdm sides) messages on the system and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -ip -lapd -cap&lt;br /&gt;
&lt;br /&gt;
=== Configuration file (optional)  ===&lt;br /&gt;
&lt;br /&gt;
The configuration file will allow to get several blades in the same file &lt;br /&gt;
&lt;br /&gt;
Example MTP2_LINK_0,MTP2_LINK_1 are on the same blade and MTP2_LINK_10,MTP2_LINK_11 are on an other blade &lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;signaling&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_0&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_1&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_10&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_11&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;/signaling&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Web&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
You can start/stop tbsigtrace via web.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Create a new application configuration: &lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Application Type       -&amp;amp;gt; User Specific&lt;br /&gt;
Bin Path               -&amp;amp;gt; @{PKG_BIN}/tbsigtrace&lt;br /&gt;
Working Path           -&amp;amp;gt; ../tbsigtrace&lt;br /&gt;
Command-line arguments -&amp;amp;gt; -adapter all -ss7 -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Create a new application instance:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Host                   -&amp;amp;gt; (put required host)&lt;br /&gt;
Application Config     -&amp;amp;gt; oamsigtrace&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
You can control the application &amp;quot;oamsigtrace&amp;quot; with the application status page OR&amp;lt;br&amp;gt;you can use the option 'o' in tboamapp (page=Application launch manager) and change the state of oamsigtrace application&amp;lt;br&amp;gt;state (0=stop 1-mgmt 2-run).&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''WARNING: tbsigtrace application should not be used all the time, otherwise it will reduce performance and fill completely your hard drive'''.&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace</id>
		<title>Toolpack Debug Application:Tbsigtrace</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace"/>
				<updated>2011-06-23T17:28:05Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Command line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tbsigtrace is a debug tool that is use to collect protocol messages. It can trace SS7, ISDN, SIP, Sigtran and CAS messages and put it in a [http://www.wireshark.org wireshark] format.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
== Application Location&amp;lt;br&amp;gt; ==&lt;br /&gt;
&lt;br /&gt;
The binary is located in the [InstallDir]/[PackageVersion]/bin/release/[Platform]/ &lt;br /&gt;
&lt;br /&gt;
Example: &lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, TMG unit (PPC 32bits) &lt;br /&gt;
&lt;br /&gt;
 /lib/tb/toolpack/pkg/2.5.55/bin/release/ppc-linux/tbsigtrace&lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, CentOS 64 bits system &lt;br /&gt;
&lt;br /&gt;
 /lib/tb/toolpack/pkg/2.5.55/bin/release/x86_64-linux64/tbsigtrace&lt;br /&gt;
&lt;br /&gt;
Version 2.5.55, Windows system &lt;br /&gt;
&lt;br /&gt;
 C:\TelcoBridges\toolpack\pkg\2.5.55\bin\release\i586-win32\tbsigtrace.exe&lt;br /&gt;
&lt;br /&gt;
== How to use it  ==&lt;br /&gt;
&lt;br /&gt;
=== Command line  ===&lt;br /&gt;
&lt;br /&gt;
Options available: &lt;br /&gt;
&lt;br /&gt;
:-d Daemon mode &lt;br /&gt;
:-name XYZ Application name &lt;br /&gt;
:-db Not used &lt;br /&gt;
:-c XYZ Configuration file to load &lt;br /&gt;
:-gw XYZ [[System Id|SystemId]] (i.e. 12358) &lt;br /&gt;
:-adapter TBXYZ Adapter name to connect or &amp;quot;all&amp;quot; to connect to all adapter in the system &lt;br /&gt;
:-ss7 Default ss7 trace activation &lt;br /&gt;
:-isdn Default isdn trace activation &lt;br /&gt;
:-ip Default ip trace activation (sip, sigtran and iua) &lt;br /&gt;
:-h248 Default h248 trace activation &lt;br /&gt;
:-lapd Default lapd trace activation&lt;br /&gt;
:-cap CAP format enabled &lt;br /&gt;
&lt;br /&gt;
==== Examples  ====&lt;br /&gt;
&lt;br /&gt;
This will gather all ss7 links from one blade and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -ss7 -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all isdn links from one blade and put them in several files &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -isdn -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all sip traces and put them in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -sip -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; In release 2.4 This will gather all sip and sigtran traces and put them in a single cap file for all adapters in the system &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter all -ip -cap&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
This will gather all h248 messages on the system and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
 tbsigtrace -gw 12358 -adapter TB000544 -h248 -cap&lt;br /&gt;
&lt;br /&gt;
=== Configuration file (optional)  ===&lt;br /&gt;
&lt;br /&gt;
The configuration file will allow to get several blades in the same file &lt;br /&gt;
&lt;br /&gt;
Example MTP2_LINK_0,MTP2_LINK_1 are on the same blade and MTP2_LINK_10,MTP2_LINK_11 are on an other blade &lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;signaling&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_0&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_1&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_10&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_11&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;/signaling&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Web&amp;lt;br&amp;gt;  ===&lt;br /&gt;
&lt;br /&gt;
You can start/stop tbsigtrace via web.&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
Create a new application configuration: &lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Application Type       -&amp;amp;gt; User Specific&lt;br /&gt;
Bin Path               -&amp;amp;gt; @{PKG_BIN}/tbsigtrace&lt;br /&gt;
Working Path           -&amp;amp;gt; ../tbsigtrace&lt;br /&gt;
Command-line arguments -&amp;amp;gt; -adapter all -ss7 -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
Create a new application instance:&amp;lt;br&amp;gt; &lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Host                   -&amp;amp;gt; (put required host)&lt;br /&gt;
Application Config     -&amp;amp;gt; oamsigtrace&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
You can control the application &amp;quot;oamsigtrace&amp;quot; with the application status page OR&amp;lt;br&amp;gt;you can use the option 'o' in tboamapp (page=Application launch manager) and change the state of oamsigtrace application&amp;lt;br&amp;gt;state (0=stop 1-mgmt 2-run).&amp;lt;br&amp;gt; &lt;br /&gt;
&lt;br /&gt;
'''WARNING: tbsigtrace application should not be used all the time, otherwise it will reduce performance and fill completely your hard drive'''.&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace</id>
		<title>Toolpack Debug Application:Tbsigtrace</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/Toolpack_Debug_Application:Tbsigtrace"/>
				<updated>2010-12-10T16:31:17Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Command line */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Tbsigtrace is a Toolpack debug tool that is use to collect protocol messages.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Where it is located ==&lt;br /&gt;
&lt;br /&gt;
The binary is located in the [InstallDir]/[PackageVersion]/bin/release/[Platform]/&lt;br /&gt;
&lt;br /&gt;
Example:&lt;br /&gt;
&lt;br /&gt;
Version 2.3.3, Windows system&lt;br /&gt;
  C:\TelcoBridges\toolpack\pkg\2.3.3\bin\release\i586-win32\tbsigtrace.exe&lt;br /&gt;
Version 2.3.5, CentOS 64 bits system&lt;br /&gt;
  /lib/tb/toolpack/pkg/2.3.5/bin/release/x86_64-linux64/tbsigtrace&lt;br /&gt;
&lt;br /&gt;
== How to use it  ==&lt;br /&gt;
&lt;br /&gt;
=== Command line  ===&lt;br /&gt;
&lt;br /&gt;
Options available: &lt;br /&gt;
&lt;br /&gt;
:-d Daemon mode &lt;br /&gt;
:-name XYZ Application name &lt;br /&gt;
:-db Not used &lt;br /&gt;
:-c XYZ Configuration file to load &lt;br /&gt;
:-gw XYZ [[System Id|SystemId]] (i.e. 12358) &lt;br /&gt;
:-adapter TBXYZ Adapter name to connect or &amp;quot;all&amp;quot; to connect to all adapter in the system &lt;br /&gt;
:-ss7 Default ss7 trace activation &lt;br /&gt;
:-isdn Default isdn trace activation &lt;br /&gt;
:-ip Default ip trace activation (sip and sigtran) &lt;br /&gt;
:-h248 Default h248 trace activation&lt;br /&gt;
:-cap CAP format enabled &lt;br /&gt;
:-regroup Regroup entity of same type&lt;br /&gt;
&lt;br /&gt;
==== Examples  ====&lt;br /&gt;
&lt;br /&gt;
This will gather all ss7 links from one blade and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter TB000544 -ss7 -regroup -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all isdn links from one blade and put them in several files &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter TB000544 -isdn -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all sip traces and put them in a single cap file &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter TB000544 -sip -regroup -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; In release 2.4 This will gather all sip and sigtran traces and put them in a single cap file for all adapters in the system &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter all -ip -regroup -cap&lt;br /&gt;
&lt;br /&gt;
This command will regroup all signaling types by group in 3 files (1 file for ss7, 1 for isdn and a last for sip( or ip)). &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter TB000544 -regroup -cap&lt;br /&gt;
&lt;br /&gt;
This will gather all h248 messages on the system and put this in a single cap file &lt;br /&gt;
&lt;br /&gt;
  tbsigtrace -gw 12358 -adapter TB000544 -h248 -cap&lt;br /&gt;
&lt;br /&gt;
=== Configuration file (optional) ===&lt;br /&gt;
&lt;br /&gt;
The configuration file will allow to get several blades in the same file &lt;br /&gt;
&lt;br /&gt;
Example MTP2_LINK_0,MTP2_LINK_1 are on the same blade and MTP2_LINK_10,MTP2_LINK_11 are on an other blade &lt;br /&gt;
&lt;br /&gt;
  &amp;amp;lt;signaling&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_0&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_1&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_10&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &amp;amp;lt;sysmgr name = &amp;quot;MTP2_LINK_11&amp;quot; grpname=&amp;quot;LS1&amp;quot; capfile=&amp;quot;true&amp;quot; /&amp;amp;gt;&lt;br /&gt;
  &lt;br /&gt;
  &amp;amp;lt;/signaling&amp;amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Web&amp;lt;br&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
You can start/stop tbsigtrace via web.&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Create a new application configuration:&lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Application Type       -&amp;amp;gt; User Specific&lt;br /&gt;
Bin Path               -&amp;amp;gt; @{PKG_BIN}/tbsigtrace&lt;br /&gt;
Working Path           -&amp;amp;gt; ../tbsigtrace&lt;br /&gt;
Command-line arguments -&amp;amp;gt; -adapter all -ss7 -regroup -cap&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Create a new application instance:&amp;lt;br&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;Name                   -&amp;amp;gt; oamsigtrace&lt;br /&gt;
Host                   -&amp;amp;gt; (put required host)&lt;br /&gt;
Application Config     -&amp;amp;gt; oamsigtrace&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
You can control the application &amp;quot;oamsigtrace&amp;quot; with the application status page OR&amp;lt;br&amp;gt;you can use the option 'o' in tboamapp (page=Application launch manager) and change the state of oamsigtrace application&amp;lt;br&amp;gt;state (0=stop 1-mgmt 2-run).&amp;lt;br&amp;gt;&lt;br /&gt;
&lt;br /&gt;
'''WARNING: tbsigtrace application should not be used all the time, otherwise it will reduce performance and fill completely your hard drive'''.&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/H.248</id>
		<title>H.248</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/H.248"/>
				<updated>2010-12-08T20:23:30Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* TelcoBridges and H.248 */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also known as Megaco, H.248 is a protocol for controlling media gateways via a [[Softswitch|softswitch]] or a [[Media gateway controller|media gateway controller]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TelcoBridges and H.248 ==&lt;br /&gt;
[[Toolpack]] now supports the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
As indicated in the diagram below, the H.248 stack is a module in the media gateway application residing on the application server. It communicates with the various Toolpack classes (CAFClass, [[CMC library|CMC Library]], CMC Class) as required via a new [[CAF:_Working_With_Call_Legs|Media Leg API]]. In turn, the media gateway application communicates with the softswitch / media gateway controller via the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:H.248 schematic.jpg|H.248 schematic.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== H.248 package support ===&lt;br /&gt;
[[Toolpack]] supports the following packages.&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1'''&lt;br /&gt;
**Protocol v2&lt;br /&gt;
**IPSec connection support&lt;br /&gt;
**Support UDP (2944 or user-defined)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1 - Basic packages'''&lt;br /&gt;
**Generic&lt;br /&gt;
**Base Root&lt;br /&gt;
**Tone generator (for extension purposes only)&lt;br /&gt;
**Tone detection (for extension purposes only)&lt;br /&gt;
**Basic DTMF generation&lt;br /&gt;
**DTMF detection&lt;br /&gt;
**Call Progress Tones Generator&lt;br /&gt;
**Basic continuity package&lt;br /&gt;
**Network package&lt;br /&gt;
**RTP package&lt;br /&gt;
**TDM Circuit package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.2 Facsimile, text conversation and call discrimination packages'''&lt;br /&gt;
**Fax/TextPhone/Modem tones detection (fax and data only)&lt;br /&gt;
**Call type discrimination package (fax and data only)&lt;br /&gt;
**IP Fax (Event: Fax Connection Change - end of fax session, call terminating)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.4 Transport over Stream Control Transmission Protocol (SCTP)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.7 Generic announcement package'''&lt;br /&gt;
**Generic announcement package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.10 Media gateway resource congestion handling package'''&lt;br /&gt;
**Congestion handling package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.11 Media gateway overload control package'''&lt;br /&gt;
**Overload control package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.13 Quality alert ceasing package'''&lt;br /&gt;
**Quality alert ceasing package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.14 Inactivity timer package'''&lt;br /&gt;
**Inactivity timer package&lt;br /&gt;
&lt;br /&gt;
== Additional details ==&lt;br /&gt;
*Support for text mode only&lt;br /&gt;
*Not supported on Solaris builds&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Megaco Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Glossary]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-06-21T19:57:02Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Play Tone with Custom Tone String */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VoIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling  ===&lt;br /&gt;
&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed. &lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer. &lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer. &lt;br /&gt;
&lt;br /&gt;
Call flow examples are available [[Call_Flow|here]].&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must:&lt;br /&gt;
 - Create call leg context for all synchronized legs, and keep them until links have been synchronized too (a leg linked to anther must be un-joined before it can be terminated)&lt;br /&gt;
 - Wait until all links have been re-synchronized (or refused using the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()''']).&lt;br /&gt;
 - Terminate all previously created call leg contexts that the application does not wish to keep, using the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Tip: The helper class CTBCAFCallLegResync has been created to simplify re-synchronizing legs. It can create and accumulate re-synchronized legs, and automatically destroy them when appropriate.&lt;br /&gt;
 - Call function AllocateCallLeg() for each synchronized leg&lt;br /&gt;
 - For legs that must not be destroyed after re-synchronization, call RemoveCallLeg() to remove them from this CTBCAFCallLegResync object. Application now has the ownership of the leg.&lt;br /&gt;
 - Upon '''OnCmcLibReady()''', application must destroy CTBCAFCallLegResync. The destructor of this class will properly refuse all legs that have been created with AllocateCallLeg(), and not removed by RemoveCallLeg().&lt;br /&gt;
You can refer to the code of the &amp;quot;Gateway&amp;quot; application for an example (search for variable mpCallLegResync).&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/H.248</id>
		<title>H.248</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/H.248"/>
				<updated>2010-06-21T15:24:41Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Planned H.248 package support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also known as Megaco, H.248 is a protocol for controlling media gateways via a [[Softswitch|softswitch]] or a [[Media gateway controller|media gateway controller]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TelcoBridges and H.248 ==&lt;br /&gt;
A version of [[Toolpack]] that supports the H.248 protocol is currently in development and is targeted for release in the first half of 2010. Further details will be provided at that time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As indicated in the diagram below, the H.248 stack will be implemented as a module in the media gateway application residing on the application server. It will communicate with the various Toolpack classes (CAFClass, [[CMC library|CMC Library]], CMC Class) as required via a new [[CAF:_Working_With_Call_Legs|Media Leg API]]. In turn, the media gateway application will communicate with the softswitch / media gateway controller via the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:H.248 schematic.jpg|H.248 schematic.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Planned H.248 package support ===&lt;br /&gt;
Support for the following packages is currently in scope.&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1'''&lt;br /&gt;
**Protocol v2&lt;br /&gt;
**IPSec connection support&lt;br /&gt;
**Support UDP (2944 or user-defined)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1 - Basic packages'''&lt;br /&gt;
**Generic&lt;br /&gt;
**Base Root&lt;br /&gt;
**Tone generator (for extension purposes only)&lt;br /&gt;
**Tone detection (for extension purposes only)&lt;br /&gt;
**Basic DTMF generation&lt;br /&gt;
**DTMF detection&lt;br /&gt;
**Basic continuity package&lt;br /&gt;
**Network package&lt;br /&gt;
**RTP package&lt;br /&gt;
**TDM Circuit package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.13 Quality alert ceasing package'''&lt;br /&gt;
**Quality alert ceasing package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.2 Facsimile, text conversation and call discrimination packages'''&lt;br /&gt;
**Fax/TextPhone/Modem tones detection (fax and data only)&lt;br /&gt;
**Call type discrimination package (fax and data only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.4 Transport over Stream Control Transmission Protocol (SCTP)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.7 Generic announcement package'''&lt;br /&gt;
**Generic announcement package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.10 Media gateway resource congestion handling package'''&lt;br /&gt;
**Congestion handling package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.11 Media gateway overload control package'''&lt;br /&gt;
**Overload control package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.14 Inactivity timer package'''&lt;br /&gt;
**Inactivity timer package&lt;br /&gt;
&lt;br /&gt;
== Additional details ==&lt;br /&gt;
*Support for text mode only&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Megaco Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Glossary]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/H.248</id>
		<title>H.248</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/H.248"/>
				<updated>2010-06-21T15:23:39Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Planned H.248 package support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also known as Megaco, H.248 is a protocol for controlling media gateways via a [[Softswitch|softswitch]] or a [[Media gateway controller|media gateway controller]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TelcoBridges and H.248 ==&lt;br /&gt;
A version of [[Toolpack]] that supports the H.248 protocol is currently in development and is targeted for release in the first half of 2010. Further details will be provided at that time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As indicated in the diagram below, the H.248 stack will be implemented as a module in the media gateway application residing on the application server. It will communicate with the various Toolpack classes (CAFClass, [[CMC library|CMC Library]], CMC Class) as required via a new [[CAF:_Working_With_Call_Legs|Media Leg API]]. In turn, the media gateway application will communicate with the softswitch / media gateway controller via the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:H.248 schematic.jpg|H.248 schematic.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Planned H.248 package support ===&lt;br /&gt;
Support for the following packages is currently in scope.&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1'''&lt;br /&gt;
**Protocol v2&lt;br /&gt;
**IPSec connection support&lt;br /&gt;
**Support UDP (2944 or user-defined)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1 - Basic packages'''&lt;br /&gt;
**Generic&lt;br /&gt;
**Base Root&lt;br /&gt;
**Tone generator (for extension purposes only)&lt;br /&gt;
**Tone detection (for extension purposes only)&lt;br /&gt;
**Basic DTMF generation&lt;br /&gt;
**DTMF detection&lt;br /&gt;
**Basic continuity package&lt;br /&gt;
**Network package&lt;br /&gt;
**RTP package&lt;br /&gt;
**TDM Circuit package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.13 Quality alert ceasing package'''&lt;br /&gt;
**Quality alert ceasing package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.2 Facsimile, text conversation and call discrimination packages'''&lt;br /&gt;
**Fax/TextPhone/Modem tones detection (fax and data only)&lt;br /&gt;
**Call type discrimination package (fax and data only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.4 Transport over Stream Control Transmission Protocol (SCTP)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.7 Generic announcement package'''&lt;br /&gt;
**Generic announcement package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.9 Advanced media server packages'''&lt;br /&gt;
**Advanced audio server base package&lt;br /&gt;
**AAS Digit collection package&lt;br /&gt;
**AAS Recording package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.10 Media gateway resource congestion handling package'''&lt;br /&gt;
**Congestion handling package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.11 Media gateway overload control package'''&lt;br /&gt;
**Overload control package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.14 Inactivity timer package'''&lt;br /&gt;
**Inactivity timer package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.16 Enhanced digit collection'''&lt;br /&gt;
**Extended DTMF detection package&lt;br /&gt;
**Enhanced DTMF detection package&lt;br /&gt;
&lt;br /&gt;
== Additional details ==&lt;br /&gt;
*Support for text mode only&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Megaco Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Glossary]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/H.248</id>
		<title>H.248</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/H.248"/>
				<updated>2010-06-21T15:23:13Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Planned H.248 package support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also known as Megaco, H.248 is a protocol for controlling media gateways via a [[Softswitch|softswitch]] or a [[Media gateway controller|media gateway controller]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TelcoBridges and H.248 ==&lt;br /&gt;
A version of [[Toolpack]] that supports the H.248 protocol is currently in development and is targeted for release in the first half of 2010. Further details will be provided at that time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As indicated in the diagram below, the H.248 stack will be implemented as a module in the media gateway application residing on the application server. It will communicate with the various Toolpack classes (CAFClass, [[CMC library|CMC Library]], CMC Class) as required via a new [[CAF:_Working_With_Call_Legs|Media Leg API]]. In turn, the media gateway application will communicate with the softswitch / media gateway controller via the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:H.248 schematic.jpg|H.248 schematic.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Planned H.248 package support ===&lt;br /&gt;
Support for the following packages is currently in scope.&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1'''&lt;br /&gt;
**Protocol v2&lt;br /&gt;
**IPSec connection support&lt;br /&gt;
**Support UDP (2944 or user-defined)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1 - Basic packages'''&lt;br /&gt;
**Generic&lt;br /&gt;
**Base Root&lt;br /&gt;
**Tone generator (for extension purposes only)&lt;br /&gt;
**Tone detection (for extension purposes only)&lt;br /&gt;
**Basic DTMF generation&lt;br /&gt;
**DTMF detection&lt;br /&gt;
**Basic continuity package&lt;br /&gt;
**Network package&lt;br /&gt;
**RTP package&lt;br /&gt;
**TDM Circuit package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.13 Quality alert ceasing package'''&lt;br /&gt;
**Quality alert ceasing package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.2 Facsimile, text conversation and call discrimination packages'''&lt;br /&gt;
**Fax/TextPhone/Modem tones detection (fax and data only)&lt;br /&gt;
**Call type discrimination package (fax and data only)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.4 Transport over Stream Control Transmission Protocol (SCTP)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.6 Dynamic tone definition package'''&lt;br /&gt;
**Dynamic tone definition&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.7 Generic announcement package'''&lt;br /&gt;
**Generic announcement package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.9 Advanced media server packages'''&lt;br /&gt;
**Advanced audio server base package&lt;br /&gt;
**AAS Digit collection package&lt;br /&gt;
**AAS Recording package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.10 Media gateway resource congestion handling package'''&lt;br /&gt;
**Congestion handling package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.11 Media gateway overload control package'''&lt;br /&gt;
**Overload control package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.14 Inactivity timer package'''&lt;br /&gt;
**Inactivity timer package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.16 Enhanced digit collection'''&lt;br /&gt;
**Extended DTMF detection package&lt;br /&gt;
**Enhanced DTMF detection package&lt;br /&gt;
&lt;br /&gt;
== Additional details ==&lt;br /&gt;
*Support for text mode only&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Megaco Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Glossary]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/H.248</id>
		<title>H.248</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/H.248"/>
				<updated>2010-06-21T15:06:09Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Planned H.248 package support */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Also known as Megaco, H.248 is a protocol for controlling media gateways via a [[Softswitch|softswitch]] or a [[Media gateway controller|media gateway controller]].&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== TelcoBridges and H.248 ==&lt;br /&gt;
A version of [[Toolpack]] that supports the H.248 protocol is currently in development and is targeted for release in the first half of 2010. Further details will be provided at that time.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
As indicated in the diagram below, the H.248 stack will be implemented as a module in the media gateway application residing on the application server. It will communicate with the various Toolpack classes (CAFClass, [[CMC library|CMC Library]], CMC Class) as required via a new [[CAF:_Working_With_Call_Legs|Media Leg API]]. In turn, the media gateway application will communicate with the softswitch / media gateway controller via the H.248 protocol.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Image:H.248 schematic.jpg|H.248 schematic.jpg]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Planned H.248 package support ===&lt;br /&gt;
Support for the following packages is currently in scope.&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1'''&lt;br /&gt;
**Protocol v2&lt;br /&gt;
**IPSec connection support&lt;br /&gt;
**Support UDP (2944 or user-defined)&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.1 - Basic packages'''&lt;br /&gt;
**Generic&lt;br /&gt;
**Base Root&lt;br /&gt;
**Tone generator (for extension purposes only)&lt;br /&gt;
**Tone detection (for extension purposes only)&lt;br /&gt;
**Basic DTMF generation&lt;br /&gt;
**DTMF detection&lt;br /&gt;
**Basic continuity package&lt;br /&gt;
**Network package&lt;br /&gt;
**RTP package&lt;br /&gt;
**TDM Circuit package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.13 Quality alert ceasing package'''&lt;br /&gt;
**Quality alert ceasing package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.2 Facsimile, text conversation and call discrimination packages'''&lt;br /&gt;
**Fax/TextPhone/Modem tones detection (fax and data only)&lt;br /&gt;
**Call type discrimination package (fax and data only)&lt;br /&gt;
**IP fax package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.4 Transport over Stream Control Transmission Protocol (SCTP)'''&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.6 Dynamic tone definition package'''&lt;br /&gt;
**Dynamic tone definition&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.7 Generic announcement package'''&lt;br /&gt;
**Generic announcement package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.9 Advanced media server packages'''&lt;br /&gt;
**Advanced audio server base package&lt;br /&gt;
**AAS Digit collection package&lt;br /&gt;
**AAS Recording package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.10 Media gateway resource congestion handling package'''&lt;br /&gt;
**Congestion handling package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.11 Media gateway overload control package'''&lt;br /&gt;
**Overload control package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.14 Inactivity timer package'''&lt;br /&gt;
**Inactivity timer package&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
*'''H.248.16 Enhanced digit collection'''&lt;br /&gt;
**Extended DTMF detection package&lt;br /&gt;
**Enhanced DTMF detection package&lt;br /&gt;
&lt;br /&gt;
== Additional details ==&lt;br /&gt;
*Support for text mode only&lt;br /&gt;
&lt;br /&gt;
== References ==&lt;br /&gt;
*[http://en.wikipedia.org/wiki/Megaco Wikipedia article]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[category:Glossary]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:34:37Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Collect Tone */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:34:17Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Play Tone with Custom Tone String */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:33:49Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Play Tone with Custom Tone String */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:32:40Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Play Tone with Signal Id String */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayEvent( Event );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;PlayEvent( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:31:28Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;PlayEvent( Event );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Custom Tone String=====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play frequencies 1000Hz and 2100Hz mixed together */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;(((#1000)+(#2100)),100,-10)&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;PlayEvent( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
===== Collect Tone =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will collect all dtmf tones */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dd/*&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;StartEventCollection( Event );&lt;br /&gt;
&amp;lt;/code&amp;gt;&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:26:32Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Play Tone with Signal Id String =====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
/* this will play dtmf 7 */&lt;br /&gt;
&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
GetOutgoingActiveLeg()-&amp;gt;PlayEvent( Event );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T15:22:34Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
Tones are defined as events, this is why to play and collect tones, you have to use general event functions. You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
CTBCMC_EVENT_ATTRIBUTE			Event;&lt;br /&gt;
Event.AddToneString( &amp;quot;dg/d7&amp;quot; );&lt;br /&gt;
(*pptrMediaLeg)-&amp;gt;PlayEvent( Event );&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T14:54:10Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Headline text */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T14:53:32Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Digits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected. &lt;br /&gt;
&lt;br /&gt;
&amp;lt;br&amp;gt; Here are examples how to play and collect digit. &lt;br /&gt;
&lt;br /&gt;
===== Play Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
===== Collect Digit  =====&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&amp;lt;pre&amp;gt;ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg&amp;amp;nbsp;!= NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt; &lt;br /&gt;
== Headline text ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T14:52:28Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Digits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here are examples how to play and collect digit.&lt;br /&gt;
&lt;br /&gt;
==== Play Digit ====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
if( ptrOutgoingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* this will play the sequence of digit 5551234 */&lt;br /&gt;
	ptrOutgoingLeg-&amp;gt;PlayDigit( &amp;quot;5551234&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Collect Digit ====&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
if( ptrIncomingLeg != NULL )&lt;br /&gt;
{&lt;br /&gt;
	/* &lt;br /&gt;
	   this will collect digits 5, any sequences of 7 digits beginning by 3 or any sequences of 7 digits &lt;br /&gt;
	   beginning by 4,5,6 or 7 followed by 5 and 5. &lt;br /&gt;
	*/&lt;br /&gt;
	ptrIncomingLeg-&amp;gt;StartDigitCollection( &amp;quot;5|3xxxxxx|[4-7]55xxxx&amp;quot; );&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T14:12:34Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Digits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example how to play and collect digit. This example plays digit 5 on the outgoing leg and collects 5 on the incoming leg when the call is answered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
TBX_RESULT CTBCAFCallTones::OnCallLegAnswered&lt;br /&gt;
(&lt;br /&gt;
  IN	PCTBCAFCallLeg						in_pCallLeg,&lt;br /&gt;
  IN	CTBCMC_PROTOCOL_ATTRIBUTE &amp;amp; 		in_ProtocolAttribute&lt;br /&gt;
)&lt;br /&gt;
{&lt;br /&gt;
	PTRCTBCAFCallLeg 			ptrIncomingLeg;&lt;br /&gt;
	PTRCTBCAFCallLeg 			ptrOutgoingLeg;&lt;br /&gt;
&lt;br /&gt;
	/*---------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
	 |  Code section&lt;br /&gt;
	 *--------------------------------------------------------------------------------------------------------------------------*/&lt;br /&gt;
	CAFCODE( CTBCAFCallTones::OnCallLegAnswered )&lt;br /&gt;
	{&lt;br /&gt;
		/* play ready tone */&lt;br /&gt;
		ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
		if( ptrOutgoingLeg != NULL )&lt;br /&gt;
		{&lt;br /&gt;
			ptrOutgoingLeg-&amp;gt;PlayDigit( &amp;quot;5&amp;quot; );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Start the digit collection of the ready digit&lt;br /&gt;
		ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
		if( ptrIncomingLeg != NULL )&lt;br /&gt;
		{&lt;br /&gt;
			ptrIncomingLeg-&amp;gt;StartDigitCollection( &amp;quot;5&amp;quot; );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		TBX_EXIT_SUCCESS( TBX_RESULT_OK );&lt;br /&gt;
	}&lt;br /&gt;
	.&lt;br /&gt;
	.&lt;br /&gt;
	.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-10T14:10:57Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Digits */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits  ===&lt;br /&gt;
You can play digits by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event when there will be a match between the asked string and the digits collected.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Here is an example how to play and collect digit. This example plays digit 5 on the outgoing leg and collects 5 on the incoming leg when the call is answered.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;lt;pre&amp;gt;&lt;br /&gt;
TBX_RESULT CTBCAFCallBehaviorTones::OnCallLegAnswered&lt;br /&gt;
(&lt;br /&gt;
  IN	PCTBCAFCallLeg						in_pCallLeg,&lt;br /&gt;
  IN	CTBCMC_PROTOCOL_ATTRIBUTE &amp;amp; 		in_ProtocolAttribute&lt;br /&gt;
)&lt;br /&gt;
{&lt;br /&gt;
TBCAF_MUTEX_GET_SCOPE_BEGIN( mpParentMutex )&lt;br /&gt;
	PTRCTBCAFCallLeg 			ptrIncomingLeg;&lt;br /&gt;
	PTRCTBCAFCallLeg 			ptrOutgoingLeg;&lt;br /&gt;
&lt;br /&gt;
	/*---------------------------------------------------------------------------------------------------------------------------&lt;br /&gt;
	 |  Code section&lt;br /&gt;
	 *--------------------------------------------------------------------------------------------------------------------------*/&lt;br /&gt;
	CAFCODE( CTBCAFCallBehaviorTones::OnCallLegAnswered )&lt;br /&gt;
	{&lt;br /&gt;
		/* play ready tone */&lt;br /&gt;
		ptrOutgoingLeg = GetOutgoingActiveLeg();&lt;br /&gt;
		if( ptrOutgoingLeg != NULL )&lt;br /&gt;
		{&lt;br /&gt;
			ptrOutgoingLeg-&amp;gt;PlayDigit( &amp;quot;5&amp;quot; );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		// Start the digit collection of the ready digit&lt;br /&gt;
		ptrIncomingLeg = GetIncomingActiveLeg();&lt;br /&gt;
		if( ptrIncomingLeg != NULL )&lt;br /&gt;
		{&lt;br /&gt;
			ptrIncomingLeg-&amp;gt;StartDigitCollection( &amp;quot;5&amp;quot; );&lt;br /&gt;
		}&lt;br /&gt;
&lt;br /&gt;
		TBX_EXIT_SUCCESS( TBX_RESULT_OK );&lt;br /&gt;
	}&lt;br /&gt;
	.&lt;br /&gt;
	.&lt;br /&gt;
	.&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/pre&amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:42:09Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package telcofax (0x8001) contains three events and two signals. Signals are: cng (0x0080) and g164 (0x0081) and events are: cng (0x0080), g164 (0x0081) and g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:22:02Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;!--code&amp;gt;test test&amp;lt;/code--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:21:47Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified when calling '''StartEventCollection()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one type of string is accepted to specify which events to collect. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;test test&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:16:11Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much more complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:13:24Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone. The syntax is much complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:12:32Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone such as ring tone. The syntax is much complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T21:12:06Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in CTBCMC_EVENT_ATTRIBUTE class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone such as ring tone. The syntax is much complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T20:54:59Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using '''AddToneString()''' available in CTBCMC_EVENT_ATTRIBUTE class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone such as ring tone. The syntax is much complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;. You can also detect all events from a package by putting a * as event id, so &amp;quot;dd/*&amp;quot; will detect all dtmf tones.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	<entry>
		<id>https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs</id>
		<title>CAF: Working With Call Legs</title>
		<link rel="alternate" type="text/html" href="https://docs.telcobridges.com/tbwiki/CAF:_Working_With_Call_Legs"/>
				<updated>2010-02-09T20:42:27Z</updated>
		
		<summary type="html">&lt;p&gt;Alexandre Lussier: /* Playing and Collecting Tones */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;== Call Leg Definition ==&lt;br /&gt;
The main mechanism through which the customer application controls the [[Toolpack]] system is via the management of call legs. The application creates a call leg (or more than one for conferencing and bridging) at the beginning of a call, then controls it through a simple, protocol-agnostic API. When a call is terminated, the call leg can be destroyed.&lt;br /&gt;
&lt;br /&gt;
A call leg is represented by an instance of the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html CTBCMCLeg] class. It represents a  full-duplex media resource and/or its associated signaling entity. Typical examples of call legs with signaling would be an [[SS7]] [[ISUP]] call with its associated [[Circuit identification code|CIC]] (mapped to a [[TDM]] interface such as a T1 [[timeslot]]) or a [[SIP]] call with its associated [[VOIP]] [[Voice codecs|codec]] resource (attached to an IP/UDP endpoint). A media-only call leg would represent a standalone TDM endpoint (such as a T1 timeslot) or a VOIP endpoint (VOIP codec resource attached to an IP/UDP endpoint). The section titled [[CAF:_Working_With_Call_Legs#Leg Creation| Leg Creation ]] will show how different types of call legs can be created.&lt;br /&gt;
&lt;br /&gt;
The CTBCMCLeg class allows a programmer to easily act upon the call leg to influence the signaling portion (e.g. accept, answer, terminate, etc) and to use the media portion as well (e.g play prompts, record voice, play or collect digits and tones).&lt;br /&gt;
&lt;br /&gt;
Other member functions are available to retrieve (and change in some cases) the call leg attributes including the media profile (e.g. parameters to the media resource) or signaling information (e.g. protocol type, called and calling party numbers, etc). Joining/unjoining (connection/disconnection) of call legs is also a typical action handled by this class for ’gateway-type’ applications. It is important to note that this class is protocol-agnostic and can handle any type of supported call legs (e.g. SIP/VOIP, [[ISDN]], SS7, Media only, etc).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===== Caveats =====&lt;br /&gt;
* Do not confuse a ''call leg'' with a ''call''. A ''call leg'' represents one full-duplex link to a party while a ''call'' represents the agglomeration of multiple (two or more) call legs. For example, a ''bridge'' is a form of ''call'' that uses two ''call legs''.&lt;br /&gt;
* Do not confuse the base class CTBCMCLeg with the class [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_call_leg.html CTBCAFCallLeg]. The later is an implementation class specialized to be used by the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_i_t_b_c_a_f_call_flow.html ITBCAFCallFlow] interface when dealing with multiple legs. It is designed to represent a leg within a call. It cannot be instanciated as a standalone object without modifications to make it independent from the ITBCAFCallFlow interface.&lt;br /&gt;
* If the overall goal is to bridge two or more call legs together, then the programmer would be advised to use the [https://docs.telcobridges.com/mediawiki/autodoc/class_t_b_c_a_f_1_1_c_t_b_c_a_f_bridge.html CTBCAFBridge] class for leg creation instead of creating call legs manually. This class already deals with the issues of handling multiple legs simultaneously.&lt;br /&gt;
&lt;br /&gt;
== Command Flow for Leg Actions in CAF ==&lt;br /&gt;
All actions requested on a leg are executed asynchronously. For each action '''DoSomething()''' on a leg,  a corresponding '''OnDoSomethingResponse()''' event will be received on the leg once Toolpack starts processing the command. If the '''OnXXXResponse()''' function does not handle the response (the default implementation is empty) and the result of the action was a failure, the default error handling function '''OnLegError()''' will be called. Most of the actions executed on a leg can take variable time to complete. In these case, an extra event will be received on the leg once the action is complete ('''OnXXXResponse()''' is always called when Toolpack '''starts''' executing the action).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For example, to play a digit sequence, one would call '''PlayDigit()'''. It would then almost immediately receive the '''OnPlayDigitResponse()''' event indicating that Toolpack has received the command. At the same time this event is called, Toolpack will start playing the digits on the leg. Once the digits play is completed, the user will receive an '''OnDigitPlayingDone()''' event.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Leg Creation ==&lt;br /&gt;
Creating a leg is always done through the definition of a ''call leg attribute''. The values entered in the ''call leg attribute'' will define the type of call leg created and its parameters. The following sections describe several scenarios in which you build a ''call leg''. Instruction will be given on how to fill the leg attributes and how to use them to create the ''call leg''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Preparing Leg Attributes ===&lt;br /&gt;
&lt;br /&gt;
==== Normal Call Leg Attributes ====&lt;br /&gt;
For calls including both the signaling and the media path, there is very few parameters that one must enter. The required parameters are:&lt;br /&gt;
* the called number,&lt;br /&gt;
* the calling number,&lt;br /&gt;
* the [[NAP | Network Access Point]].&lt;br /&gt;
&lt;br /&gt;
Toolpack will automatically select an available channel in the specified NAP to make the call leg. Only NAPs of type ''SS7'', ''ISDN'' or ''SIP'' can be specified for call leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
The following code snippet shows how to build the attributes.&lt;br /&gt;
  PTRCTBCMC_CALL_LEG_ATTRIBUTE ptrOutgoingLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute = tbnew CTBCMC_CALL_LEG_ATTRIBUTE();&lt;br /&gt;
 &lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCalledNumber()            = &amp;quot;123-4567&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetCallingNumber()           = &amp;quot;987-6543&amp;quot;;&lt;br /&gt;
  ptrOutgoingLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_SS7_MONTREAL&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
==== Media-only Leg Attributes ====&lt;br /&gt;
For media-only legs, no signaling information is needed but the user can specify which media channel to use and which media profile to use. The only required parameters are the [[NAP | Network Access Point]] and the leg type. Only NAPs of type ''MEDIA TDM'' or ''MEDIA VOIP'' can be specified for media-only leg attribute (see [[NAP#NAP Types|NAP Types]]).&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION           pMediaDesc;&lt;br /&gt;
  PTRCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE ptrLegAttribute;&lt;br /&gt;
 &lt;br /&gt;
  ptrLegAttribute = tbnew CTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE();&lt;br /&gt;
  pMediaDesc      = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  &lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetNetworkAccessPoint()      = &amp;quot;NAP_MEDIA_1&amp;quot;; &lt;br /&gt;
  pMediaDesc-&amp;gt;Type                              = TBCMC_MEDIA_TYPE_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Transport                         = TBCMC_MEDIA_TRANSPORT_TDM or TBCMC_MEDIA_TRANSPORT_IP;&lt;br /&gt;
&lt;br /&gt;
When only the NAP and type are specified, Toolpack will automatically select an available channel in the specified NAP to allocate the media path. For  ''MEDIA TDM'' NAPs, a trunk/timeslot from the specified NAP will be chosen by Toolpack. For ''MEDIA VOIP'' NAPs, an IP interface and port from the specified NAP will be chosen.&lt;br /&gt;
&lt;br /&gt;
If the user wants to specify which media channel to use, it can do so by adding extra information in the leg attribute. For TDM legs, a trunk name and a timeslot number can be specified.&lt;br /&gt;
&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.Type            = TBCMC_MEDIA_SETTINGS_TYPE_TDM_AUDIO;&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.TdmAudio.un8Timeslot     = 5;&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName,&lt;br /&gt;
      &amp;quot;TRUNK_TORONTO_1&amp;quot;,&lt;br /&gt;
      sizeof(pMediaDesc-&amp;gt;Settings.TdmAudio.szTrunkName)&lt;br /&gt;
  );&lt;br /&gt;
&lt;br /&gt;
For VOIP legs, the user can control the media by providing local [[SDP]] and peer SDP. Setting the local SDP defines the codec and IP/port used to for the received media stream. Most of the time, the IP address and port should be left empty to let Toolpack choose an available port. Setting the peer SDP defines the codec and IP/port used for the transmitted media stream. Note that Toolpack only allows for the same codec to be used in RX and TX. If both local SDP and peer SDP are specified, codecs that are not in '''both''' SDP will be filtered out.&lt;br /&gt;
&lt;br /&gt;
For details on how to fill the TBX_SDP_INFO structure needed for SetLocalSDP and SetPeerSDP, see [[CAF:_Filling_SDP_Structures|Filling an SDP Structures]].&lt;br /&gt;
&lt;br /&gt;
  TBX_RESULT               Result;&lt;br /&gt;
  TBX_SDP_INFO             SdpInfo;&lt;br /&gt;
  PTBCMC_MEDIA_DESCRIPTION pMediaDesc;&lt;br /&gt;
 &lt;br /&gt;
  pMediaDesc = ptrLegAttribute-&amp;gt;GetProfile().GetMediaDescription();&lt;br /&gt;
  pMediaDesc-&amp;gt;Settings.PacketAudio.Type         = TBCMC_MEDIA_SETTINGS_TYPE_PACKET_AUDIO;&lt;br /&gt;
 &lt;br /&gt;
  // Set Local SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;&amp;quot;, 0, SdpInfo);                 // No IP specified, Toolpack will choose one&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
 &lt;br /&gt;
  // Set Peer SDP&lt;br /&gt;
  Result = BuildSdpInfo(&amp;quot;10.0.0.15&amp;quot;, 5000, SdpInfo);     // Using peer IP address and port&lt;br /&gt;
  TBCAF_EXIT_ON_ERROR( Result, &amp;quot;BuildSdpInfo failed.&amp;quot; );&lt;br /&gt;
  ptrLegAttribute-&amp;gt;GetProfile().SetPeerSDP(SdpInfo);&lt;br /&gt;
&lt;br /&gt;
=== Creating the Leg ===&lt;br /&gt;
Once the leg attributes have been filled, creating the leg in Toolpack is only a matter of creating a CTBCMCLeg object and calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CreateCall '''CreateCall()'''] on it. No action is taken when an instance of a CTBCMCLeg is created. Call resources are only allocated in the Toolpack system when '''CreateCall()''' is called on the object. &lt;br /&gt;
&lt;br /&gt;
  pCallLeg = new CTBCMCLeg( mun32LegId++, ptrLegAttribute, this, 0, &amp;amp;mLegMutex );&lt;br /&gt;
  pCallLeg-&amp;gt;CreateCall();&lt;br /&gt;
&lt;br /&gt;
For legs with signaling, the '''CreateCall()''' will trigger the sending of the call setup message (SIP Invite, SS7 IAM, etc.). In that case, the media resources are not allocated immediately. They will be allocated only when the signaling part of the call setup is complete. If the application requests a media action (PlayFile, StartDigitCollection, etc.) on the leg, this will immediately trigger the allocation of the media resources even if the call is not yet answered (used for early media for example).&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow SignalingMediaLeg Creation.JPG|thumb|center|350px|Call flow for creation of leg with signaling]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For media-only legs, the media ressources will always be allocated as soon as '''CreateCall()''' is called.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow MediaOnlyLeg Creation.JPG|thumb|center|350px|Call flow for media-only leg creation]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Once a call is fully active (call answered and media allocated), event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnProfileChanged '''OnProfileChanged()'''] will be sent on the leg. In the cases where the user had not specified the IP/port to use, once this event is received, the media profile has been updated with the values chosen by Toolpack and the updated values can be retrieved using the functions '''GetLocalSDP()''' and '''GetPeerSDP()''' of the profile.&lt;br /&gt;
Note that the '''OnProfileChanged()''' event is also sent after the media profile has been modified with the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ChangeProfile '''ChangeProfile()'''] function (see [[#Modifying Media Profile|Modifying Media Profile]]) and when a connected peer has requested it (through a SIP re-INVITE for example).  &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
See [[CAF:_Leg_Creation_Samples|Leg creation example]] for sample code of leg creation in different scenarios.&lt;br /&gt;
&lt;br /&gt;
=== Caveats ===&lt;br /&gt;
* The call leg attribute is an object containing the call leg information (called/calling numbers, media profile, etc) that needs to be allocated by the caller and used when creating the leg object. It will be freed automatically when the leg is destroyed (it uses a shared-pointer so it is in fact destroyed when there are no more reference to it).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Interaction with Legs ==&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Digits ===&lt;br /&gt;
You can add tones you want to play by using [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html#CTBCMC_EVENT_ATTRIBUTE::AddToneString '''AddToneString()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___e_v_e_n_t___a_t_t_r_i_b_u_t_e.html CTBCMC_EVENT_ATTRIBUTE] class.&lt;br /&gt;
You can then play digits defined by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayDigit '''PlayDigit()'''] on a leg. Toolpack will receive the request and play the digits. Once digits are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitPlayingDone '''OnDigitPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect digits played. To start the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartDigitCollection '''StartDigitCollection()'''] on the leg. Note that you will have to specify which digits you want to collect before starting the digit collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the digit collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopDigitCollection '''StopDigitCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnDigitCollected '''OnDigitCollected()'''] event on each digit received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Collecting Tones ===&lt;br /&gt;
You can add tones you want to play by using '''AddToneString()''' available in CTBCMC_EVENT_ATTRIBUTE class.&lt;br /&gt;
You can then play events by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayEvent '''PlayEvent()'''] on a leg. Toolpack will receive the request and play the events. Once events are played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventPlayingDone '''OnEventPlayingDone()'''] event. Note that you can cancel an event to be played by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::CancelEvent '''CancelEvent()'''] on the leg after a '''PlayEvent()''' has been called.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Two kinds of string can be passed to '''AddToneString()''' to play a tone. The first type is to play well known tones such as dtmf and fax tone. The syntax is really simple and is based on H248 package and signal ids. The first component of the string is the package id and the second is the signal id, both formated in string. So, to play dtmf 0, you have to format the following string: &amp;quot;dg/d0&amp;quot;, where &amp;quot;dg&amp;quot; is for package &amp;quot;dtmf generation&amp;quot; and &amp;quot;d0&amp;quot; is for &amp;quot;dtmf 0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The second type of string is to play custom tone such as ring tone. The syntax is much complicated than the first one, but it follows a well described syntax which can be found in [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.6-200011-I!!PDF-E&amp;amp;type=items/.pdf '''H248.6 Dynamic Tone Definition Package''']. This kind of string allows you to specify frequencies, duration, amplitude and repeating count of the tone. You can also specify well known tones and change their default duration, amplitude and repeating count. It is possible to describe a sequence of tones or frequencies that are played in one segment. Here are some examples of the syntax:&lt;br /&gt;
&lt;br /&gt;
*;Frequencies 400Hz and 600Hz mixed together for 200ms, amplitude at -10dB and repeating 3 times (playing 4 times):&lt;br /&gt;
:*(((#400)+(#600)),200,-10)*3&lt;br /&gt;
:&lt;br /&gt;
*;Dtmf 5 repeated infinitly: &lt;br /&gt;
:*((0x0005,0x0015))*0&lt;br /&gt;
:&lt;br /&gt;
*;Multifrequency tone 8: &lt;br /&gt;
:*((mfg,mf8))&lt;br /&gt;
:&lt;br /&gt;
*;Frequency 440Hz played for 300ms at -10dB followed by frequency 600Hz played for 200ms at -5dB and then followed by dtmf 2, all this repeated infinitly: &lt;br /&gt;
:*((#440,300,-10),(#600,200,-5),(0x0005,0x0012))*0&lt;br /&gt;
:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to collect events played. To start the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StartEventCollection '''StartEventCollection()'''] on the leg. Note that you will have to specify which events you want to collect before starting the event collection by calling '''AddToneString()''' on a CTBCMC_EVENT_ATTRIBUTE object. To stop the event collection, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopEventCollection '''StopEventCollection()''']. A leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnEventCollected '''OnEventCollected()'''] event on each event received that correspond to a tone string specified with the previously call to '''AddToneString()'''.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Only one string is accepted to collect events. The string is the same as the first type to play event. Signal ids that are also event id are accepted. This means that you can ask to collect &amp;quot;dg/d0&amp;quot; (dtmf generation/dtmf 0) and the detection will be done anyway. But, when the event is detected, it's the event id that will be returned, which means that &amp;quot;dd/d0&amp;quot; (dtmf detection/dtmf 0) will be returned instead of &amp;quot;dg/d0&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The most commonly used package are 5 and 6 [http://www.itu.int/rec/dologin_pub.asp?lang=e&amp;amp;id=T-REC-H.248.1-200509-I!!PDF-E&amp;amp;type=items/.pdf '''(H248.1 Annex E)''']: dtmf generation and dtmf detection. As H248 does not define events and signals for fax tone, we added a special package to do so. Package tbfax (0x0251) contains three events and two signals: cng (0x0080), g164 (0x0081) and only for detection g165 (0x0082).&lt;br /&gt;
&lt;br /&gt;
=== Collecting digits and tones while call legs are joined ===&lt;br /&gt;
By default, when two call legs are joined together through function CTBCMCCallLeg::Join(), tone collection is automatically disabled.&lt;br /&gt;
One of the arguments of the Join() function (&amp;quot;in_fDisableToneWhileJoined&amp;quot;) will allow to control if automatic tone collection feature is used or not on a call.&lt;br /&gt;
&lt;br /&gt;
Why is Toolpack disabling tone collection on joined legs by default?&lt;br /&gt;
That's because tone collection introduces a 40ms delay in the audio connection (required to provide tone suppression), and most of the time it is no more require to collect digits while two call legs are joined, so it would be useless to leave 40ms delay while tone collection is no more required.&lt;br /&gt;
&lt;br /&gt;
=== Playing and Recording Audio Files ===&lt;br /&gt;
You can play an audio stream on a leg by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PlayStream '''PlayStream()'''] on it. To specify which audio stream you want to play, you have to specify it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html#CTBCMC_PLAY_ATTRIBUTE::AddPlayFilePath '''AddPlayFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___p_l_a_y___a_t_t_r_i_b_u_t_e.html CTBCMC_PLAY_ATTRIBUTE] class. Toolpack will receive the request and play the stream. Once it is played, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamPlayingDone '''OnStreamPlayingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can also configure a leg to record an audio stream. First you must specify file paths to record by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html#CTBCMC_RECORD_ATTRIBUTE::AddRecFilePath '''AddRecFilePath()'''] available in [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c___r_e_c_o_r_d___a_t_t_r_i_b_u_t_e.html CTBCMC_RECORD_ATTRIBUTE] class. The you can call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RecordStream '''RecordStream()'''] on a leg. Once the stream is recorded, the leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnStreamRecordingDone '''OnStreamRecordingDone()'''] event.&lt;br /&gt;
&lt;br /&gt;
You can pause an active playing or recording stream by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::PauseStream '''PauseStream()'''] and you can resume it by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::ResumeStream '''ResumeStream()''']. If you want to stop an active playing or recording stream, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::StopStream '''StopStream()'''] on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Modifying Media Profile ===&lt;br /&gt;
It is always possible to modify the media profile of a leg after it was created. This can be used for example to change to a more compressed codec if bandwidth resources become sparse or to switch to T.38 Fax after a fax tone was detected.&lt;br /&gt;
&lt;br /&gt;
The media profile is stored in the leg attributes and can be modified like this :&lt;br /&gt;
  TBX_SDP_INFO                        SdpInfo;&lt;br /&gt;
  PCTBCMC_MEDIA_ONLY_LEG_ATTRIBUTE    pMediaLegAttribute;&lt;br /&gt;
  &lt;br /&gt;
  pMediaLegAttribute = pCallLeg-&amp;gt;GetAttributes().GetMediaOnlyLegAttribute();&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().GetLocalSDP(SdpInfo);&lt;br /&gt;
  Strncpy&lt;br /&gt;
  (&lt;br /&gt;
      SdpInfo.aConnections[0].szIp,&lt;br /&gt;
      &amp;quot;&amp;quot;,&lt;br /&gt;
      sizeof( SdpInfo.aConnections[0].szIp )&lt;br /&gt;
  );&lt;br /&gt;
  SdpInfo.Capabilities.aCapGroups[0].aSimultaneousCap[0].un16UdpPort = 0;&lt;br /&gt;
  pMediaLegAttribute-&amp;gt;GetProfile().SetLocalSDP(SdpInfo);&lt;br /&gt;
  &lt;br /&gt;
  pCallLeg-&amp;gt;ChangeProfile();&lt;br /&gt;
&lt;br /&gt;
Once the attributes have been modified, '''ChangeProfile()''' must be called to activate the new profile. In the case of media-only legs, activating a modified profile will immediately reallocate the media resources. In the case of a SIP call leg, activating the new profile will trigger a new negotiation with the peer (INVITE-RESPONSE) after which the media resources will be allocated using the newly negotiated codecs.&lt;br /&gt;
&lt;br /&gt;
Once the profile change has completed (or failed), event '''OnProfileChanged()''' will be received on the leg. &lt;br /&gt;
&lt;br /&gt;
For SIP call leg, if the peer entity sends us re-INVITE with a new SDP during a call, the media resource will be automatically updated and event '''OnProfileChanged()''' will be received on the leg.&lt;br /&gt;
&lt;br /&gt;
=== Controlling the Signaling ===&lt;br /&gt;
When a call leg receives the '''OnCallLegPresent()''' event, it indicates an incoming call. To confirm that the call contains sufficient valid information to process the call on the system, you have to call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AcceptCall '''AcceptCall()'''] on the leg. If a call leg receives the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAccepted '''OnCallAccepted()'''] event, it means that an outgoing call has been accepted by the remote peer. This event usually means that the calling number has been accepted and that the call is currently being processed.&lt;br /&gt;
&lt;br /&gt;
After an incoming call has been accepted, a call leg can notify the remote peer that the incoming call has been put in the &amp;quot;ringing&amp;quot; state by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AlertCall '''AlertCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAlerting '''OnCallAlerting()'''] event when an outgoing call has been put in the &amp;quot;ringing&amp;quot; state by the remote peer.&lt;br /&gt;
&lt;br /&gt;
When an incoming call is answered, a call leg can notify the remote peer of the incoming call answered by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::AnswerCall '''AnswerCall()''']. In the same way, a call leg will receive [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallAnswered '''OnCallAnswered()'''] event when an outgoing call has been answered by the remote peer.&lt;br /&gt;
&lt;br /&gt;
SendCallSuppInfo/OnCallSuppInfo&lt;br /&gt;
&lt;br /&gt;
== Leg Termination ==&lt;br /&gt;
&lt;br /&gt;
Terminating a call leg is a 2 steps process:&lt;br /&gt;
# Call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::TerminateCall '''TerminateCall()''']&lt;br /&gt;
# Free leg object on [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminated '''OnCallTerminated()''']&lt;br /&gt;
&lt;br /&gt;
When '''TerminateCall()''' is called, the Toolpack framework will start leg termination. This includes media resources freeing and, for leg with signaling, sending of the appropriate signaling message to terminate the call. Once the media resources have been deallocated and call termination signaling is done, Toolpack will call '''OnCallTerminated()''' on the leg. When this event is received on the leg, this leg no more exists in Toolpack and the object can thus be freed. At the end of the '''OnCallTerminated()''' handler, the default implementation of class CTBCMCLeg will call method [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Free '''Free()'''] on the leg's [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_free_listener.html ITBCMCFreeListener] interface. The ITBCMCFreeListener to use can be specified either in the CTBCMCLeg constructor and by calling [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::SetFreeListener '''SetFreeListener()'''] on the leg. The leg can be it's own ''FreeListener'', in which it just 'delete' itself when its '''Free()''' method is called. An application specific ''FreeListener'' can be used for cases where other action needs to be taken before the leg is deleted. An example could be the case where the leg object was allocated from a pool and it should be returned to that pool instead of being deleted.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from application.jpg|thumb|center|350px|Call flow for leg termination initiated by user application]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In some situation, it is possible that leg termination be initiated by Toolpack. This can happen for leg with signaling, when a call termination request is received on the signaling channel. It can also happen on any type of leg in the event of sudden media resource unavailability and other media resource or signaling error. In these cases, the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnCallTerminatingIndication '''OnCallTerminatingIndication()'''] is sent to the leg. On reception of this event, the application should initiate call termination as shown below.&lt;br /&gt;
&lt;br /&gt;
[[Image:TerminateCall from Toolpack.jpg|thumb|center|350px|Call flow for leg termination initiated by Toolpack]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In case of internal system error or major communication lost with the Toolpack engine, Toolpack would send the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnLegTerminated '''OnLegTerminated()'''] event. This event indicates that the leg does not exist anymore on the Toolpack side and the user should free its object without trying any other interaction with Toolpack through it.&lt;br /&gt;
&lt;br /&gt;
== Leg Synchronization on Failover ==&lt;br /&gt;
When a Toolpack application is restarted or when a standby application is activated, it goes through a synchronization phase with the Toolpack framework. During this phase, Toolpack informs the application of all the already allocated call legs through the '''OnCallLegSync()''' event of the [https://docs.telcobridges.com/mediawiki/autodoc/class_i_t_b_c_m_c_lib_user.html ITBCMCLibUser] interface (this interface must be implemented by all user applications). One event will be received for each leg being synchronized. The course of action to take when receiving a leg synchronization event depends on the ability of the application to resynchronize its states with theses legs.&lt;br /&gt;
&lt;br /&gt;
* If the application can't resynchronize active legs or if it does not want to resychronize the leg for which it is receiving an '''OnCallLegSync()''' event, it must refuse the leg by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLeg '''RefuseLeg()'''].&lt;br /&gt;
*If the application wants the resynchronize the leg or if it does not yet have enough information to decide, it must create a CTBCMCLeg object using the leg attributes received in the event.&lt;br /&gt;
&lt;br /&gt;
Once all '''OnCallLegSync()''' have been sent, Toolpack will start synchronization of the links between legs through '''OnLinkSync()'''. This event indicates that two legs are connected together. It can be used by the application to rebuild its internal states. As for the legs, unwanted links can be refused by calling the static function [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::RefuseLink '''RefuseLink()'''].&lt;br /&gt;
&lt;br /&gt;
When all links have been synchronized, Toolpack sends the '''OnCmcLibReady()''' event indicating that active resources synchronization is complete. At that moment, the application has all the information available on the Toolpack side to determine if the legs should be kept or release. Any leg that the application does not want to keep can be refused by calling '''RefuseLeg()''' on it. For all legs that have not been refused, an event [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::OnSyncDone '''OnSyncDone()'''] will be sent on the leg. Once this event has been received on a leg, the leg is fully functional and the application can start calling any usual Toolpack function on it.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Application Restart.jpg|thumb|center|350px|Call flow for leg synchronization]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
===Loss of Communication with Toolpack Engine===&lt;br /&gt;
If communication is lost with the Toolpack Engine, event '''OnCmcLibNotReady()''' will be sent to the application. It indicates that the Toolpack framework is no more accessible. The legs are still valid at that time but no action can be executed on them as long the CmcLib is not ready. If the connection with the Toolpack Engine is not back up in less than 10 seconds, the CmcLib will declare a major communication loss and will call '''OnLegTerminated()''' on all the legs. In that case, when communication is regained with the Toolpack Engine, the synchronization sequence will start again from the beginning.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Passed 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart passed 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
If the communication is regained before the 10 seconds timeout, event '''OnCmcLibReady()''' will be sent and the application can then continue working normally with its existing call legs. Note that you can also receive '''OnLegTerminated()''' on some legs before receiving the '''OnCmcLibReady()''' if those legs were in a transient state when disconnection occurred.&lt;br /&gt;
&lt;br /&gt;
[[Image:CallFlow Sync After Comm Restart Within 10sec.jpg|thumb|center|350px|Call flow for leg synchronization after a communication restart within 10 seconds.]]&lt;br /&gt;
&lt;br /&gt;
== Bridging the Media Path ==&lt;br /&gt;
=== Join  ===&lt;br /&gt;
&lt;br /&gt;
To bridge the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Join '''Join()'''] on one of the leg, giving the second leg as a parameter. This will connect the media path between the two legs according to the link properties set on the leg on which '''Join()''' is called. These link properties can be modified by overloading the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetJoinAttributes '''GetJoinAttributes()''']. The important attribute to set is '''IsFullDuplex()''' that indicates if the connection will be made full-duplex (A&amp;amp;lt;--&amp;amp;gt;B) or half-duplex (A--&amp;amp;gt;B). Prior to release 2.5.2, the default connection mode is half-duplex. For all release version 2.5.2 or higher, the default connection mode is full-duplex.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' If two legs are already connected in half-duplex and you want to connect them in full-duplex, you must first Unjoin() the legs, then Join() them in full-duplex. You can '''NOT''' only do another half-duplex in the opposite direction. &lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
When legs are joined, it creates a link identified with a unique ''link id''. It is the responsibility of the application to provide this unique ''link id'' by implementing the [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::GetLinkId '''GetLinkId()'''] function of the leg. It is planned to allow the user to provide a value of '0' to let the Toolpack system automatically choose a ''link id'', but as of this writing this feature is not yet available.&lt;br /&gt;
&lt;br /&gt;
'''Warning:''' When two legs are joined, the application must ensure that '''GetLinkId()''' on both leg will return the right ''link id''. This will ensure that when the link needs to be removed, both A-&amp;gt;Unjoin() and B-&amp;gt;Unjoin() will work correctly.&lt;br /&gt;
&lt;br /&gt;
==== Setting the link properties  ====&lt;br /&gt;
&lt;br /&gt;
In your leg class, add a member variable to store the join attributes for that leg. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE mJoinAttribute;&lt;br /&gt;
&lt;br /&gt;
Then set the join properties you want in your leg class constructor (or at any other location that will run '''before''' the '''Join()''' is done: &lt;br /&gt;
&lt;br /&gt;
  mJoinAttribute.IsFullDuplex() = TBX_TRUE;&lt;br /&gt;
&lt;br /&gt;
Last, implement the '''GetJoinAttributes()''' function. &lt;br /&gt;
&lt;br /&gt;
  CTBCMC_JOIN_ATTRIBUTE &amp;amp;amp; CH248Termination::GetJoinAttributes()&lt;br /&gt;
  {&lt;br /&gt;
  	return mJoinAttribute;&lt;br /&gt;
  }&lt;br /&gt;
&lt;br /&gt;
==== Broadcasting a media source ====&lt;br /&gt;
At the time of writing this, broadcast of a single media source to multiple destinations is not yet possible.&lt;br /&gt;
&lt;br /&gt;
=== Unjoin ===&lt;br /&gt;
To disconnect the media path between two legs, one must call [https://docs.telcobridges.com/mediawiki/autodoc/class_c_t_b_c_m_c_leg.html#CTBCMCLeg::Unjoin'''Unjoin()'''] on any of the legs. The '''GetLinkId()''' function of the leg on which '''Unjoin()''' is called must return the ''link id'' that was used when the legs were joined.&lt;br /&gt;
&lt;br /&gt;
[[category:CAF]]&lt;br /&gt;
[[category:Needs revising]]&lt;/div&gt;</summary>
		<author><name>Alexandre Lussier</name></author>	</entry>

	</feed>