<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Wandering through the Wilderness - Tapi</title>
    <link>http://www.julmar.com/blog/mark/</link>
    <description>... a journey through WPF, MVVM and .NET4</description>
    <language>en-us</language>
    <copyright>Mark Smith</copyright>
    <lastBuildDate>Sat, 06 Feb 2010 17:56:38 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>mark@julmar.com</managingEditor>
    <webMaster>mark@julmar.com</webMaster>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=a7333798-461f-4471-96b1-d4375c0ee379</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,a7333798-461f-4471-96b1-d4375c0ee379.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,a7333798-461f-4471-96b1-d4375c0ee379.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=a7333798-461f-4471-96b1-d4375c0ee379</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I cannot count how many times people have requested the source code to the ATAPI.NET
or ITAPI3 projects.  My response has always been that I was unable to release
it due to ownership issues (it was developed under contract for a client).  I
am pleased to announce this morning that I have worked through those issues and have
been granted permission to release the project in it’s entirety as source code on
CodePlex!
</p>
        <p>
Here’s their new homes:  <a title="http://atapi.codeplex.com/" href="http://atapi.codeplex.com/">http://atapi.codeplex.com/</a> and <a href="http://itapi3.codeplex.com">http://itapi3.codeplex.com</a></p>
        <p>
I’ll open up discussion board access there as well for Q&amp;A.  If you would
like to contribute to the project, shoot me an email and we’ll see about getting you
access!
</p>
      </body>
      <title>ATAPI.NET and ITAPI3 source code availability!</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,a7333798-461f-4471-96b1-d4375c0ee379.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2010/02/06/ATAPINETAndITAPI3SourceCodeAvailability.aspx</link>
      <pubDate>Sat, 06 Feb 2010 17:56:38 GMT</pubDate>
      <description>&lt;p&gt;
I cannot count how many times people have requested the source code to the ATAPI.NET
or ITAPI3 projects.&amp;nbsp; My response has always been that I was unable to release
it due to ownership issues (it was developed under contract for a client).&amp;nbsp; I
am pleased to announce this morning that I have worked through those issues and have
been granted permission to release the project in it’s entirety as source code on
CodePlex!
&lt;/p&gt;
&lt;p&gt;
Here’s their new homes:&amp;nbsp; &lt;a title="http://atapi.codeplex.com/" href="http://atapi.codeplex.com/"&gt;http://atapi.codeplex.com/&lt;/a&gt; and &lt;a href="http://itapi3.codeplex.com"&gt;http://itapi3.codeplex.com&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I’ll open up discussion board access there as well for Q&amp;amp;A.&amp;nbsp; If you would
like to contribute to the project, shoot me an email and we’ll see about getting you
access!
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,a7333798-461f-4471-96b1-d4375c0ee379.aspx</comments>
      <category>.NET</category>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=599288b9-351f-471d-abda-f75ba99219e8</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,599288b9-351f-471d-abda-f75ba99219e8.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,599288b9-351f-471d-abda-f75ba99219e8.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=599288b9-351f-471d-abda-f75ba99219e8</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
It's been a while since I updated the ATAPI assembly, I've fixed a couple of minor
bugs that were reported and updated the samples to compile with VS2008.  I've
also added two new events onto the TapiPhone class so you can see state changes and
button presses - somehow I missed that when I added the phone support.
</p>
        <p>
Finally, there's now online documentation available at 
</p>
        <p>
          <a href="http://www.julmar.com/atapi_help/index.aspx">http://www.julmar.com/atapi_help/index.aspx</a>
        </p>
        <p>
You can download the updated assembly, help file and samples from 
</p>
        <p>
          <a href="http://www.julmar.com/tapi/atapinet.zip">http://www.julmar.com/tapi/atapinet.zip</a>
        </p>
        <p>
Have fun!
</p>
      </body>
      <title>ATAPI assembly updated!</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,599288b9-351f-471d-abda-f75ba99219e8.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2008/07/23/ATAPIAssemblyUpdated.aspx</link>
      <pubDate>Wed, 23 Jul 2008 17:54:45 GMT</pubDate>
      <description>&lt;p&gt;
It's been a while since I updated the ATAPI assembly, I've fixed a couple of minor
bugs that were reported and updated the samples to compile with VS2008.&amp;nbsp; I've
also added two new events onto the TapiPhone class so you can see state changes and
button presses - somehow I missed that when I added the phone support.
&lt;/p&gt;
&lt;p&gt;
Finally, there's now online documentation available at 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.julmar.com/atapi_help/index.aspx"&gt;http://www.julmar.com/atapi_help/index.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
You can download the updated assembly, help file and samples from 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.julmar.com/tapi/atapinet.zip"&gt;http://www.julmar.com/tapi/atapinet.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Have fun!
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,599288b9-351f-471d-abda-f75ba99219e8.aspx</comments>
      <category>.NET</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=61b8e49c-f652-4897-a4cf-087b3ac6bb2e</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,61b8e49c-f652-4897-a4cf-087b3ac6bb2e.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,61b8e49c-f652-4897-a4cf-087b3ac6bb2e.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=61b8e49c-f652-4897-a4cf-087b3ac6bb2e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Sales of the TSP++ products have steadily fallen over the past 5 years, so much so
that I decided two years ago to release the 2.x product into the open-source community,
and now I am doing the same for the server edition. 
</p>
        <p>
The download is available <a href="http://www.julmar.com/_Media/tspv3053.exe">here</a> and
requires a key to install it - use <span style="font-family: 'Lucida Grande'; font-size: 14px;"></span></p>
        <p>
          <span style="font-family: 'Lucida Grande'; font-size: 14px;">J35M-3KXo-q60T</span>
        </p>
        <p>
          <span style="font-family: 'Lucida Grande'; font-size: 14px;">
            <span style="font-family: Times; font-size: 16px;">
            </span>
          </span>
        </p>
        <p style="font-family: Verdana; font-size: 12px;">
which will let you install the full product. Documentation and samples are all part
of the image so have fun!
</p>
        <p>
        </p>
      </body>
      <title>TSP++ 3.0 is now free!</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,61b8e49c-f652-4897-a4cf-087b3ac6bb2e.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2007/07/13/TSP30IsNowFree.aspx</link>
      <pubDate>Fri, 13 Jul 2007 21:46:33 GMT</pubDate>
      <description>&lt;p&gt;
Sales of the TSP++ products have steadily fallen over the past 5 years, so much so
that I decided two years ago to release the 2.x product into the open-source community,
and now I am doing the same for the server edition. 
&lt;/p&gt;
&lt;p&gt;
The download is available &lt;a href="http://www.julmar.com/_Media/tspv3053.exe"&gt;here&lt;/a&gt; and
requires a key to install it - use &lt;span style="font-family: 'Lucida Grande'; font-size: 14px;"&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family: 'Lucida Grande'; font-size: 14px;"&gt;J35M-3KXo-q60T&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="font-family: 'Lucida Grande'; font-size: 14px;"&gt;&lt;span style="font-family: Times; font-size: 16px;"&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="font-family: Verdana; font-size: 12px;"&gt;
which will let you install the full product. Documentation and samples are all part
of the image so have fun!
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,61b8e49c-f652-4897-a4cf-087b3ac6bb2e.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=7bf0a572-660a-4134-95ba-bee2ae82988e</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,7bf0a572-660a-4134-95ba-bee2ae82988e.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,7bf0a572-660a-4134-95ba-bee2ae82988e.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=7bf0a572-660a-4134-95ba-bee2ae82988e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">I've updated ATAPI.NET in the samples page <a href="http://www.julmar.com/samples/atapinet.zip">http://www.julmar.com/samples/atapinet.zip</a> with
several fixes and support for conferences, full transfers and phone support. I think
almost everything is now wrapped - if you find any missing functions that you want/need
ping me and I'll see what I can do.</body>
      <title>New Version of ATAPI.NET available</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,7bf0a572-660a-4134-95ba-bee2ae82988e.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/12/08/NewVersionOfATAPINETAvailable.aspx</link>
      <pubDate>Fri, 08 Dec 2006 18:11:22 GMT</pubDate>
      <description>I've updated ATAPI.NET in the samples page 
&lt;a href="http://www.julmar.com/samples/atapinet.zip"&gt;http://www.julmar.com/samples/atapinet.zip&lt;/a&gt; with several fixes and support for conferences, full transfers and phone support.  I think almost everything is now wrapped - if you find any missing functions that you want/need ping me and I'll see what I can do.</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,7bf0a572-660a-4134-95ba-bee2ae82988e.aspx</comments>
      <category>.NET</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=a080551e-30d1-47d5-b8a4-1007481b9528</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,a080551e-30d1-47d5-b8a4-1007481b9528.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,a080551e-30d1-47d5-b8a4-1007481b9528.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=a080551e-30d1-47d5-b8a4-1007481b9528</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font face="Times New Roman" size="3">I've gotten several questions on this topic
so I thought it might be a good thing to show in a blog.  Recording with TAPI
3.1 is actually pretty easy if you are running on Windows XP or better.  TAPI
3.1 provides some simple filename-based methods to dump the conversation into a .WAV
file.  If you want to control the file, or stream it somewhere else, it's a bit
more difficult and Microsoft provides a decent sample with the platform SDK that does
it.</font>
        </p>
        <p>
          <font face="Times New Roman" size="3">Here's a simple example -- in this scenerio
we will create a new outgoing call, connect it and then setup an outgoing stream to
play a welcome message:</font>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font size="3">
              <font color="#0000ff">TapiCall</font> currCall <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> selectedAddress.CreateCall(numberToDial,
LINEADDRESSTYPES.PhoneNumber, TAPIMEDIATYPES.AUDIO);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (currCall
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
{<br />
   currCall.Connect(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">false</span>);<br /></font>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font size="3">  
playbackTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> currCall.RequestTerminal(TTerminal.FilePlaybackTerminal,
TAPIMEDIATYPES.AUDIO, TERMINAL_DIRECTION.TD_CAPTURE);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
if</span> (playbackTerminal !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
   {<br />
      playbackTerminal.MediaPlayList <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
{ MESSAGE_PROMPT };<br />
      currCall.SelectTerminalOnCall(playbackTerminal);<br />
   }<br />
}</font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font face="Verdana" color="#003300" size="2">When
the call is actually connected, then we will start the playbackTerminal stream and
begin recording the conversation - this would typically be done in the TE_CALLSTATE
handler:</font>
          </span>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font size="3">
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e.State
== CALL_STATE.CS_CONNECTED &amp;&amp; playbackTerminal !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
// Start the playback message..</span><br />
   playbackTerminal.Start();<br />
   </font>
              <font size="3">
                <font color="#008000">// Begin recording the
conversation - may be half-duplex..<br /></font>   RecordConversation("RecordedMessage.wav");<br /></font>
            </span>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font size="3">}<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">else</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">if</span> (e.State
== CALL_STATE.CS_DISCONNECTED)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
// Stop recording when the call terminates.</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
if</span> (recordTerminal !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
      recordTerminal.Stop();<br /><br />
   recordTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
   playbackTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
}<br /></font>
            </span>
          </span>
        </p>
        <p>
          <font face="Times New Roman" size="3">The code for recording the conversation is pretty
simple as well, given a filename, just get a recording terminal and assign it. 
TAPI will take care of creating the file and writing contents into it.</font>
        </p>
        <p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font size="3">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> RecordConversation(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span> fileName)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
// This code only works on XP or better (TAPI 3.1).</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">  
if</span> (currCall !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
   {<br />
      recordTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> currCall.RequestTerminal(TTerminal.FileRecordingTerminal,
TAPIMEDIATYPES.MULTITRACK, TERMINAL_DIRECTION.TD_RENDER);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">     
if</span> (recordTerminal !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
      {<br />
         recordTerminal.RecordFileName <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> fileName;<br />
         currCall.SelectTerminalOnCall(recordTerminal);<br />
         recordTerminal.Start();<br />
      }<br /><font color="#0000ff">   </font>}<br />
}<br /></font>
          </span>
        </p>
        <p>
          <font face="Times New Roman" size="3">Finis.<br /></font>
        </p>
      </body>
      <title>You can be just like the government and record telephone conversations.. with TAPI 3.1</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,a080551e-30d1-47d5-b8a4-1007481b9528.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/06/19/YouCanBeJustLikeTheGovernmentAndRecordTelephoneConversationsWithTAPI31.aspx</link>
      <pubDate>Mon, 19 Jun 2006 15:41:45 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font face="Times New Roman" size=3&gt;I've gotten several questions on this topic so
I thought it might be a good thing to show in a blog.&amp;nbsp; Recording with TAPI 3.1
is actually pretty easy if you are running on Windows XP or better.&amp;nbsp; TAPI 3.1
provides some simple filename-based methods to dump the conversation into a .WAV file.&amp;nbsp;
If you want to control the file, or stream it somewhere else, it's a bit more difficult
and Microsoft provides a decent sample with the platform SDK that does it.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Times New Roman" size=3&gt;Here's a simple example -- in this scenerio we
will create a new outgoing call, connect it and then setup an outgoing stream to play
a welcome message:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font size=3&gt;&lt;font color=#0000ff&gt;TapiCall&lt;/font&gt; currCall &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; selectedAddress.CreateCall(numberToDial,
LINEADDRESSTYPES.PhoneNumber, TAPIMEDIATYPES.AUDIO);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (currCall
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp; currCall.Connect(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;false&lt;/span&gt;);&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font size=3&gt;&amp;nbsp;&amp;nbsp;
playbackTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; currCall.RequestTerminal(TTerminal.FilePlaybackTerminal,
TAPIMEDIATYPES.AUDIO, TERMINAL_DIRECTION.TD_CAPTURE);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (playbackTerminal !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; playbackTerminal.MediaPlayList &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
{ MESSAGE_PROMPT };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; currCall.SelectTerminalOnCall(playbackTerminal);&lt;br&gt;
&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#003300 size=2&gt;When
the call is actually connected, then we will start the playbackTerminal stream and
begin recording the conversation - this would typically be done in the TE_CALLSTATE
handler:&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font size=3&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e.State
== CALL_STATE.CS_CONNECTED &amp;amp;&amp;amp; playbackTerminal !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// Start the playback message..&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; playbackTerminal.Start();&lt;br&gt;
&amp;nbsp;&amp;nbsp; &lt;/font&gt;&lt;font size=3&gt;&lt;font color=#008000&gt;//&amp;nbsp;Begin recording the conversation
- may be&amp;nbsp;half-duplex..&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp; RecordConversation("RecordedMessage.wav");&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font size=3&gt;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;else&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;if&lt;/span&gt; (e.State
== CALL_STATE.CS_DISCONNECTED)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// Stop recording when the call terminates.&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (recordTerminal !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordTerminal.Stop();&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp; recordTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp; playbackTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
}&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&gt; 
&lt;p&gt;
&lt;font face="Times New Roman" size=3&gt;The code for recording the conversation is pretty
simple as well, given a filename, just get a recording terminal and assign it.&amp;nbsp;
TAPI will take care of creating the file and writing contents into it.&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font size=3&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; RecordConversation(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt; fileName)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
// This code only works on XP or better (TAPI 3.1).&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (currCall !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; currCall.RequestTerminal(TTerminal.FileRecordingTerminal,
TAPIMEDIATYPES.MULTITRACK, TERMINAL_DIRECTION.TD_RENDER);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
if&lt;/span&gt; (recordTerminal !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordTerminal.RecordFileName &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; fileName;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; currCall.SelectTerminalOnCall(recordTerminal);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; recordTerminal.Start();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&lt;font color=#0000ff&gt;&amp;nbsp;&amp;nbsp; &lt;/font&gt;}&lt;br&gt;
}&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Times New Roman" size=3&gt;Finis.&lt;br&gt;
&lt;/font&gt;
&lt;/p&gt;
&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,a080551e-30d1-47d5-b8a4-1007481b9528.aspx</comments>
      <category>.NET</category>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=79d8f859-419f-429f-a500-4cf8bbe2d928</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,79d8f859-419f-429f-a500-4cf8bbe2d928.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,79d8f859-419f-429f-a500-4cf8bbe2d928.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=79d8f859-419f-429f-a500-4cf8bbe2d928</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Minor, but breaking update for ATAPI.NET (version number has changed).  It was
pointed out to me that the assembly wasn't very VB.NET friendly in that it didn't
show any events at the TapiManager level and you couldn't use the UI to hook it all
up.  That's fixed and all the line-level events are also exposed at the TapiManager
level for those who want to use VB.NET with the 2.0 wrapper.
</p>
        <p>
 
</p>
      </body>
      <title>ATAPI.NET updated for VB.NET</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,79d8f859-419f-429f-a500-4cf8bbe2d928.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/04/20/ATAPINETUpdatedForVBNET.aspx</link>
      <pubDate>Thu, 20 Apr 2006 14:01:49 GMT</pubDate>
      <description>&lt;p&gt;
Minor, but breaking update for ATAPI.NET (version number has changed).&amp;nbsp; It was
pointed out to me that the assembly wasn't very VB.NET friendly in that it didn't
show any events at the TapiManager level and you couldn't use the UI to hook it all
up.&amp;nbsp; That's fixed and all the line-level events are also exposed at the TapiManager
level for those who want to use VB.NET with the 2.0 wrapper.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,79d8f859-419f-429f-a500-4cf8bbe2d928.aspx</comments>
      <category>.NET</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=8edc8427-e71b-4d90-b526-1431890ca7ca</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,8edc8427-e71b-4d90-b526-1431890ca7ca.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,8edc8427-e71b-4d90-b526-1431890ca7ca.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=8edc8427-e71b-4d90-b526-1431890ca7ca</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have updated ITAPI3 to fix a couple of reported bugs -- the TE_FILETERMINAL event
wasn't always being raised and the TCall.GenerateCustomTone didn't work properly. 
Both of these issues are fixed in the latest drop.  Enjoy!
</p>
      </body>
      <title>ITAPI3 update posted</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,8edc8427-e71b-4d90-b526-1431890ca7ca.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/30/ITAPI3UpdatePosted.aspx</link>
      <pubDate>Thu, 30 Mar 2006 23:16:09 GMT</pubDate>
      <description>&lt;p&gt;
I have updated ITAPI3 to fix a couple of reported bugs -- the TE_FILETERMINAL event
wasn't always being raised and the TCall.GenerateCustomTone didn't work properly.&amp;nbsp;
Both of these issues are fixed in the latest drop.&amp;nbsp; Enjoy!
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,8edc8427-e71b-4d90-b526-1431890ca7ca.aspx</comments>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=7513eebc-2aed-4ff4-a1db-744ded447cc3</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,7513eebc-2aed-4ff4-a1db-744ded447cc3.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,7513eebc-2aed-4ff4-a1db-744ded447cc3.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=7513eebc-2aed-4ff4-a1db-744ded447cc3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I've posted a new version of ATAPI.NET which supports consultation transfers and a
simple phone sample that shows off how to use the features.  In addtiion, this
version of ATAPI.NET has a couple of bug fixes that were rolled in from a production
project over the past couple of weeks to fix some weird startup/shutdown issues when
a LINE_REINIT is reported by TAPI.  You can get the new code from our samples
link -- <a href="http://www.julmar.com/samples.htm">http://www.julmar.com/samples.htm</a></p>
        <p>
 
</p>
      </body>
      <title>Updated ATAPI samples and assembly</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,7513eebc-2aed-4ff4-a1db-744ded447cc3.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/17/UpdatedATAPISamplesAndAssembly.aspx</link>
      <pubDate>Fri, 17 Mar 2006 15:59:23 GMT</pubDate>
      <description>&lt;p&gt;
I've posted a new version of ATAPI.NET which supports consultation transfers and a
simple phone sample that shows off how to use the features.&amp;nbsp; In addtiion, this
version of ATAPI.NET has a couple of bug fixes that were rolled in from a production
project over the past couple of weeks to fix some weird startup/shutdown issues when
a LINE_REINIT is reported by TAPI.&amp;nbsp; You can get the new code from our samples
link -- &lt;a href="http://www.julmar.com/samples.htm"&gt;http://www.julmar.com/samples.htm&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,7513eebc-2aed-4ff4-a1db-744ded447cc3.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=e1ebbee2-20ed-4541-af2c-417d4dea110e</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,e1ebbee2-20ed-4541-af2c-417d4dea110e.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,e1ebbee2-20ed-4541-af2c-417d4dea110e.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=e1ebbee2-20ed-4541-af2c-417d4dea110e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Forwarding lines with ATAPI.NET is simple and easy (assuming, of course, that the
underlying TSP supports it).
</p>
        <p>
The first step is knowing whether a given line device even <em>supports</em> forwarding. 
This is trivial:
</p>
        <font color="#008080" size="2">
          <p>
            <font face="Courier New">TapiManager</font>
          </p>
        </font>
        <font face="Courier New">
          <font color="#000000" size="2"> mgr = </font>
          <font color="#0000ff" size="2">new</font>
          <font color="#000000" size="2">
          </font>
          <font color="#008080" size="2">TapiManager</font>
          <font color="#000000" size="2">(</font>
          <font color="#800000" size="2">"ForwardingTest"</font>
          <font size="2">
            <font color="#000000">);</font>
          </font>
        </font>
        <font size="2">
          <p>
          </p>
        </font>
        <font face="Courier New">
          <font color="#0000ff" size="2">foreach</font>
          <font size="2"> (</font>
          <font color="#008080" size="2">TapiLine</font>
          <font size="2"> line </font>
          <font color="#0000ff" size="2">in</font>
        </font>
        <font face="Courier New">
          <font size="2"> mgr.Lines)<br />
{<br />
   </font>
          <font color="#0000ff" size="2">if</font>
        </font>
        <font size="2">
          <font face="Courier New"> (line.Capabilities.SupportsForwarding)<br />
   {<br />
      <font color="#008080" size="2">Console</font><font size="2">.WriteLine(</font><font color="#800000" size="2">"Line
{0} supports forwarding!"</font></font>
          <font face="Courier New">
            <font size="2">, line.Name);<br /></font>   }<br />
}</font>
        </font>
        <p>
          <font size="2">Once we've identified a specific line, we can look at each address
and get more information such as the <em>types</em> of forwarding supported. 
For example, we might be able to forward to different numbers based on specific conditions
such as whether the call goes unanswered vs. whether the address is in use and returning
a busy signal.  We might also be able to forward specific inbound callers (very
useful to get rid of your bosses calls).  We can get this information from the <strong>Capabilities</strong> of
the <strong>TapiAddress</strong> object:
</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#0000ff" size="2">foreach</font>
            <font size="2"> (</font>
            <font color="#008080" size="2">TapiAddress</font>
            <font size="2"> addr </font>
            <font color="#0000ff" size="2">in</font>
          </font>
          <font face="Courier New">
            <font size="2"> line.Addresses)<br />
{<br />
   </font>
            <font color="#008080" size="2">Console</font>
            <font size="2">.WriteLine(</font>
            <font color="#800000" size="2">"Forwarding
modes supported on {0} are {1}"</font>
          </font>
          <font face="Courier New" size="2">,
addr.Address, addr.Capabilities.SupportedForwardingModes);<br /></font>
          <font size="2">
            <font face="Courier New">}</font>
          </font>
        </p>
        <p>
We can also retrieve any existing forwarding information through the <strong>Status</strong> of
the <strong>TapiAddress</strong>:
</p>
        <p>
          <font face="Courier New">
            <font color="#0000ff" size="2">foreach</font>
            <font size="2"> (</font>
            <font color="#008080" size="2">ForwardInfo</font>
            <font size="2"> fwd </font>
            <font color="#0000ff" size="2">in</font>
          </font>
          <font face="Courier New">
            <font size="2"> addr.Status.ForwardingInformatioin)<br />
   </font>
            <font color="#008080" size="2">Console</font>
            <font size="2">.WriteLine(</font>
            <font color="#800000" size="2">"\t{0}
to {1}:{2}"</font>
          </font>
          <font size="2">
            <font face="Courier New">, fwd.ForwardMode,
fwd.DestinationAddressType, fwd.DestinationAddress);</font>
          </font>
        </p>
        <p>
This outputs: "Unconditional to PhoneNumber:1234" on a forwarded line I setup.
</p>
        <p>
Finally, the big question is how to change the forwarding information, this is pretty
easy as well.  You can set forwarding information on two levels, the entire line
(which impacts all addresses), or a specific address.  This is done through two
methods present on both <strong>TapiAddress</strong> and <strong>TapiLine </strong>which
are <strong>Forward </strong>and <strong>CancelForward</strong>.  So, to cancel
all forwarding in effect on every line we could do the following:
</p>
        <font size="2">
          <p>
          </p>
        </font>
        <font face="Courier New">
          <font color="#008080" size="2">Console</font>
          <font size="2">.WriteLine(</font>
          <font color="#800000" size="2">"Canceling
all forwards:"</font>
        </font>
        <font face="Courier New">
          <font size="2">);<br /></font>
          <font color="#0000ff" size="2">foreach</font>
          <font size="2"> (</font>
          <font color="#008080" size="2">TapiLine</font>
          <font size="2"> line </font>
          <font color="#0000ff" size="2">in</font>
        </font>
        <font face="Courier New">
          <font size="2"> mgr.Lines)<br />
{<br />
   </font>
          <font color="#0000ff" size="2">if</font>
        </font>
        <font face="Courier New" size="2"> (line.Capabilities.SupportsForwarding)<br />
   {<br />
      </font>
        <font face="Courier New" color="#0000ff" size="2">try<br />
      </font>
        <font face="Courier New">
          <font size="2">{<br />
         line.CancelForward();<br />
      }<br />
      </font>
          <font color="#0000ff" size="2">catch</font>
          <font size="2"> (</font>
          <font color="#008080" size="2">TapiException</font>
        </font>
        <font face="Courier New">
          <font size="2"> ex)<br />
      {<br />
         </font>
          <font color="#008080" size="2">Console</font>
          <font size="2">.WriteLine(</font>
          <font color="#800000" size="2">"{0}
- {1}"</font>
        </font>
        <font size="2">
          <font face="Courier New">, line, ex.Message);<br />
      }<br />
   }<br />
}</font>
          <p>
Or, to setup the forwarding as above, I can issue a call to the <strong>Forward</strong> method:
</p>
          <font size="2">
            <p>
            </p>
          </font>
          <font face="Courier New">
            <font color="#008080" size="2">ForwardInfo</font>
            <font size="2">[]
fwdInfo = </font>
            <font color="#0000ff" size="2">new</font>
            <font size="2">
            </font>
            <font color="#008080" size="2">ForwardInfo</font>
          </font>
          <font face="Courier New">
            <font size="2">[]
{<br />
      </font>
            <font color="#0000ff" size="2">new</font>
            <font size="2">
            </font>
            <font color="#008080" size="2">ForwardInfo</font>
            <font size="2">(</font>
            <font color="#008080" size="2">ForwardingMode</font>
            <font size="2">.Unconditional,
0, </font>
            <font color="#800000" size="2">"1234"</font>
          </font>
          <font size="2">
            <font face="Courier New">)<br />
};</font>
            <p>
            </p>
          </font>
          <font face="Courier New">
            <font color="#0000ff" size="2">foreach</font>
            <font size="2"> (</font>
            <font color="#008080" size="2">TapiLine</font>
            <font size="2"> line </font>
            <font color="#0000ff" size="2">in</font>
          </font>
          <font face="Courier New">
            <font size="2"> mgr.Lines)<br />
{<br />
   </font>
            <font color="#0000ff" size="2">if</font>
          </font>
          <font face="Courier New" size="2"> (line.Capabilities.SupportsForwarding)<br />
   {<br />
      </font>
          <font face="Courier New" color="#0000ff" size="2">try<br />
      </font>
          <font face="Courier New">
            <font size="2">{<br />
         line.Forward(fwdInfo, 5, </font>
            <font color="#0000ff" size="2">null</font>
          </font>
          <font face="Courier New">
            <font size="2">);<br />
      }<br />
      </font>
            <font color="#0000ff" size="2">catch</font>
            <font size="2"> (</font>
            <font color="#008080" size="2">TapiException</font>
          </font>
          <font face="Courier New">
            <font size="2"> ex)<br />
      {<br />
         </font>
            <font color="#008080" size="2">Console</font>
            <font size="2">.WriteLine(</font>
            <font color="#800000" size="2">"{0}
- {1}"</font>
          </font>
          <font size="2">
            <font face="Courier New">, line.Name, ex.Message);<br />
      }<br />
   }<br />
}</font>
            <p>
The <strong>ForwardInfo</strong> class describes a single forwarding instruction and
you pass an array of these info the <strong>Forward</strong> method to indicate how
things are to be managed.  Exceptions need to be handled because the TAPI service
provider might not allow the particular forwarding at this point in time, or the destination
might not be allowed, etc.
</p>
            <p>
Under the covers this will issue a <strong>lineForward</strong> request with a <strong>LINEFORWARDLIST</strong> setup
for each of the <strong>ForwardInfo</strong> structures.
</p>
            <p>
That about covers it!  Ping me with any questions if you want.
</p>
            <p>
 
</p>
          </font>
        </font>
      </body>
      <title>Fun with forwarding..</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,e1ebbee2-20ed-4541-af2c-417d4dea110e.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/15/FunWithForwarding.aspx</link>
      <pubDate>Wed, 15 Mar 2006 20:43:58 GMT</pubDate>
      <description>&lt;p&gt;
Forwarding lines with ATAPI.NET is simple and easy (assuming, of course, that the
underlying TSP supports it).
&lt;/p&gt;
&lt;p&gt;
The first step is knowing whether a given line device even &lt;em&gt;supports&lt;/em&gt; forwarding.&amp;nbsp;
This is trivial:
&lt;/p&gt;
&lt;font color=#008080 size=2&gt; 
&lt;p&gt;
&lt;font face="Courier New"&gt;TapiManager&lt;/font&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#000000 size=2&gt; mgr = &lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font color=#000000 size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiManager&lt;/font&gt;&lt;font color=#000000 size=2&gt;(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"ForwardingTest"&lt;/font&gt;&lt;font size=2&gt;&lt;font color=#000000&gt;);&lt;/font&gt;&lt;/font&gt;&lt;/font&gt;&gt;
&lt;font size=2&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiLine&lt;/font&gt;&lt;font size=2&gt; line &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; mgr.Lines)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt; (line.Capabilities.SupportsForwarding)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Line
{0} supports forwarding!"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;, line.Name);&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/font&gt;&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font size=2&gt;Once we've identified a specific line, we can look at each address and
get more information such as the &lt;em&gt;types&lt;/em&gt; of forwarding supported.&amp;nbsp; For
example, we might be able to forward to different numbers based on specific conditions
such as whether the call goes unanswered vs. whether the address is in use and returning
a busy signal.&amp;nbsp; We might also be able to forward specific inbound callers (very
useful to get rid of your bosses calls).&amp;nbsp; We can get this information from the &lt;strong&gt;Capabilities&lt;/strong&gt; of
the &lt;strong&gt;TapiAddress&lt;/strong&gt; object:
&lt;/p&gt;
&lt;p&gt;
&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiAddress&lt;/font&gt;&lt;font size=2&gt; addr &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; line.Addresses)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Forwarding
modes supported on&amp;nbsp;{0} are {1}"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt;,
addr.Address, addr.Capabilities.SupportedForwardingModes);&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
We can also retrieve any existing forwarding information through the &lt;strong&gt;Status&lt;/strong&gt; of
the &lt;strong&gt;TapiAddress&lt;/strong&gt;:&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;ForwardInfo&lt;/font&gt;&lt;font size=2&gt; fwd &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; addr.Status.ForwardingInformatioin)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"\t{0}
to {1}:{2}"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;, fwd.ForwardMode,
fwd.DestinationAddressType, fwd.DestinationAddress);&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
This outputs: "Unconditional to PhoneNumber:1234" on a forwarded line I setup.
&lt;/p&gt;
&lt;p&gt;
Finally, the big question is how to change the forwarding information, this is pretty
easy as well.&amp;nbsp; You can set forwarding information on two levels, the entire line
(which impacts all addresses), or a specific address.&amp;nbsp; This is done through two
methods present on both &lt;strong&gt;TapiAddress&lt;/strong&gt; and &lt;strong&gt;TapiLine &lt;/strong&gt;which
are &lt;strong&gt;Forward &lt;/strong&gt;and &lt;strong&gt;CancelForward&lt;/strong&gt;.&amp;nbsp; So, to cancel
all forwarding in effect on every line we could do the following:
&lt;/p&gt;
&lt;font size=2&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Canceling
all forwards:"&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;);&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiLine&lt;/font&gt;&lt;font size=2&gt; line &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; mgr.Lines)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; (line.Capabilities.SupportsForwarding)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New" color=#0000ff size=2&gt;try&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;line.CancelForward();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;catch&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiException&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"{0}
- {1}"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;, line, ex.Message);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/font&gt;&gt;
&lt;p&gt;
Or, to setup the forwarding as above, I can issue a call to the &lt;strong&gt;Forward&lt;/strong&gt; method:
&lt;/p&gt;
&lt;font size=2&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#008080 size=2&gt;ForwardInfo&lt;/font&gt;&lt;font size=2&gt;[]
fwdInfo = &lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;ForwardInfo&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;[]
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;ForwardInfo&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#008080 size=2&gt;ForwardingMode&lt;/font&gt;&lt;font size=2&gt;.Unconditional,
0, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"1234"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;)&lt;br&gt;
};&lt;/font&gt;&gt;
&lt;p&gt;
&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiLine&lt;/font&gt;&lt;font size=2&gt; line &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; mgr.Lines)&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New" size=2&gt; (line.Capabilities.SupportsForwarding)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New" color=#0000ff size=2&gt;try&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;line.Forward(fwdInfo, 5, &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;catch&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiException&lt;/font&gt;&lt;/font&gt;&lt;font face="Courier New"&gt;&lt;font size=2&gt; ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"{0}
- {1}"&lt;/font&gt;&lt;/font&gt;&lt;font size=2&gt;&lt;font face="Courier New"&gt;, line.Name, ex.Message);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/font&gt;&gt;
&lt;p&gt;
The &lt;strong&gt;ForwardInfo&lt;/strong&gt; class describes a single forwarding instruction and
you pass an array of these info the &lt;strong&gt;Forward&lt;/strong&gt; method to indicate how
things are to be managed.&amp;nbsp; Exceptions need to be handled because the TAPI service
provider might not allow the particular forwarding at this point in time, or the destination
might not be allowed, etc.
&lt;/p&gt;
&lt;p&gt;
Under the covers this will issue a &lt;strong&gt;lineForward&lt;/strong&gt; request with a &lt;strong&gt;LINEFORWARDLIST&lt;/strong&gt; setup
for each of the &lt;strong&gt;ForwardInfo&lt;/strong&gt; structures.
&lt;/p&gt;
&lt;p&gt;
That about covers it!&amp;nbsp; Ping me with any questions if you want.
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/font&gt;&lt;/font&gt;&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,e1ebbee2-20ed-4541-af2c-417d4dea110e.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=3a275fbf-e292-4017-a783-5b40dc1f0ec7</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,3a275fbf-e292-4017-a783-5b40dc1f0ec7.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,3a275fbf-e292-4017-a783-5b40dc1f0ec7.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=3a275fbf-e292-4017-a783-5b40dc1f0ec7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So, a question was asked "How do I determine what's happening in the TAPI3 wrapper"? 
The answer is you turn on the internal trace source -- ITapi3 was built with a build
in tracing facility to tell you when it had any underlying interface or COM failures
and it's easy to activate.  First, add an <strong>Application Configuration File</strong> to
your project.  Open that file and add the following lines:
</p>
        <font size="2">
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <font color="#0000ff" size="2">
              <p>
&lt;?
</p>
            </font>
            <font color="#800000" size="2">xml</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">version</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">1.0</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">encoding</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">utf-8</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2"> ?&gt;<br />
&lt;</font>
            <font color="#800000" size="2">configuration</font>
            <font color="#0000ff" size="2">&gt;<br />
   &lt;</font>
            <font color="#800000" size="2">system.diagnostics</font>
            <font color="#0000ff" size="2">&gt;<br />
      &lt;</font>
            <font color="#800000" size="2">sources</font>
            <font color="#0000ff" size="2">&gt;<br />
         &lt;</font>
            <font color="#800000" size="2">source</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">name</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">ITapiTrace</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">switchName</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">tapiSwitch</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">switchType</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">System.Diagnostics.SourceSwitch</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">&gt;<br />
            &lt;</font>
            <font color="#800000" size="2">listeners</font>
            <font color="#0000ff" size="2">&gt;<br />
               </font>
            <font color="#0000ff" size="2">&lt;</font>
            <font color="#800000" size="2">add</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">name</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">MyTraceLog</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">type</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">System.Diagnostics.TextWriterTraceListener</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">initializeData</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">MyTrace.txt</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2"> /&gt;<br />
            &lt;/</font>
            <font color="#800000" size="2">listeners</font>
            <font color="#0000ff" size="2">&gt;<br />
         &lt;/</font>
            <font color="#800000" size="2">source</font>
            <font color="#0000ff" size="2">&gt;<br />
      &lt;/</font>
            <font color="#800000" size="2">sources</font>
            <font color="#0000ff" size="2">&gt;<br />
      &lt;</font>
            <font color="#800000" size="2">switches</font>
            <font color="#0000ff" size="2">&gt;<br />
         &lt;</font>
            <font color="#800000" size="2">add</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">name</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">tapiSwitch</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">
            </font>
            <font color="#ff0000" size="2">value</font>
            <font color="#0000ff" size="2">=</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2">All</font>
            <font size="2">"</font>
            <font color="#0000ff" size="2"> /&gt;<br />
      &lt;/</font>
            <font color="#800000" size="2">switches</font>
            <font color="#0000ff" size="2">&gt;<br />
   &lt;/</font>
            <font color="#800000" size="2">system.diagnostics</font>
            <font color="#0000ff" size="2">&gt;<br />
&lt;/</font>
            <font color="#800000" size="2">configuration</font>
            <font color="#0000ff" size="2">&gt;</font>
            <p>
              <font face="Verdana" color="#000000" size="2">This will create a file called "MyTrace.txt"
in your working directory.  The important line is the <strong>source</strong> tag
which identifies the internal <strong>TraceSource</strong> object used by the ITapi3
library.  Inside this file will be the internal TAPI3 calls being made for your
application.  As an example, the following trace shows me that several underlying
COM errors occurred in the running of a simple TAPI3 application -- it was unable
to retrieve the ITTerminal interface from the <strong>ITAddressEvent</strong> interface
(which actually isn't really an error), failed to open the line (because Unimodem
won't allow the media type VOICE to be passed for my modem), and failed to set the
play list for this MSP -- [<font face="Courier New">0x80040216</font><font face="Verdana">]
is actually a DirectShow error [VFW_E_NOT_FOUND].</font></font>
            </p>
            <p>
ITapiTrace Verbose: 0 : Creating ITTAPI instance<br />
ITapiTrace Verbose: 0 : Hooking up connection sink to ITTAPI interface<br />
ITapiTrace Information: 0 : ITTapi::put_EventFilter(0x8001F) hr=0x0<br />
ITapiTrace Error: 0 : COM Hresult 0x80040004 "The MEDIATYPE passed in to this method
was invalid." generated <br />
   at JulMar.Tapi3.TapiException.ThrowExceptionForHR(Int32 hr)<br />
   at JulMar.Tapi3.TTapi.RegisterCallNotifications(ITAddress* pitf, Int16
vbMonitor, Int16 vbOwner, Int32 supportedMediaTypes)<br />
   at JulMar.Tapi3.TAddress.Open(TAPIMEDIATYPES supportedMediaTypes)<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 5, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 4, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 3, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 2, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 1, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 0, Terminal=<br />
ITapiTrace Verbose: 0 : Processing TapiCallNotificationEventArgs: Event=CNE_OWNER,
Call=TCall: 171360625 CS_OFFERING<br />
ITapiTrace Verbose: 0 : Processing TapiCallStateEventArgs: Call=TCall: 171360625 CS_OFFERING,
State=CS_OFFERING, Cause=CEC_NONE<br />
ITapiTrace Error: 0 : COM Hresult 0x80040216 "" generated <br />
   at JulMar.Tapi3.TapiException.ThrowExceptionForHR(Int32 hr)<br />
   at JulMar.Tapi3.TTerminal.set_MediaPlayList(String[] fileList)<br />
   at AnsMachine.AutoAttendantForm.AnswerCall()<br />
   at AnsMachine.AutoAttendantForm.OnCallState(Object sender, TapiCallStateEventArgs
e)<br />
ITapiTrace Verbose: 0 : Processing TapiCallStateEventArgs: Call=TCall: 171360625 CS_DISCONNECTED,
State=CS_DISCONNECTED, Cause=CEC_DISCONNECT_NORMAL<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 5, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 4, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 3, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 2, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 1, Terminal=<br />
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055<br />
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 0, Terminal=<br />
ITapiTrace Error: 0 : ITTapi::Shutdown hr=0x0<br /></p>
            <p>
 
</p>
          </span>
        </font>
        <strong>
          <font color="#000000">
          </font>
        </strong>
      </body>
      <title>Debugging the underlying Telephony calls</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,3a275fbf-e292-4017-a783-5b40dc1f0ec7.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/07/DebuggingTheUnderlyingTelephonyCalls.aspx</link>
      <pubDate>Tue, 07 Mar 2006 23:18:50 GMT</pubDate>
      <description>&lt;p&gt;
So, a question was asked "How do I determine what's happening in the TAPI3 wrapper"?&amp;nbsp;
The answer is you turn on the internal trace source -- ITapi3 was built with a build
in tracing facility to tell you when it had any underlying interface or COM failures
and it's easy to activate.&amp;nbsp; First, add an &lt;strong&gt;Application Configuration File&lt;/strong&gt; to
your project.&amp;nbsp; Open that file and add the following lines:
&lt;/p&gt;
&lt;font size=2&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#0000ff size=2&gt; 
&lt;p&gt;
&amp;lt;?
&lt;/font&gt;&lt;font color=#800000 size=2&gt;xml&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;version&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;1.0&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;encoding&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;utf-8&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; ?&amp;gt;&lt;br&gt;
&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;configuration&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;system.diagnostics&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;sources&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;source&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;name&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;ITapiTrace&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;switchName&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;tapiSwitch&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;switchType&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;System.Diagnostics.SourceSwitch&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;listeners&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;add&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;name&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;MyTraceLog&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;type&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;System.Diagnostics.TextWriterTraceListener&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;initializeData&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;MyTrace.txt&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;listeners&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;source&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;sources&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;switches&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;&lt;/font&gt;&lt;font color=#800000 size=2&gt;add&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;name&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;tapiSwitch&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; &lt;/font&gt;&lt;font color=#ff0000 size=2&gt;value&lt;/font&gt;&lt;font color=#0000ff size=2&gt;=&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt;All&lt;/font&gt;&lt;font size=2&gt;"&lt;/font&gt;&lt;font color=#0000ff size=2&gt; /&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;switches&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;system.diagnostics&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;br&gt;
&amp;lt;/&lt;/font&gt;&lt;font color=#800000 size=2&gt;configuration&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;gt;&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font face=Verdana color=#000000 size=2&gt;This will create a file called "MyTrace.txt"
in your working directory.&amp;nbsp; The important line is the &lt;strong&gt;source&lt;/strong&gt; tag
which identifies the internal &lt;strong&gt;TraceSource&lt;/strong&gt; object used by the ITapi3
library.&amp;nbsp; Inside this file will be the internal TAPI3 calls being made for your
application.&amp;nbsp; As an example, the following trace shows me that several underlying
COM errors occurred in the running of a simple TAPI3 application -- it was unable
to retrieve the ITTerminal interface from the &lt;strong&gt;ITAddressEvent&lt;/strong&gt; interface
(which actually isn't really an error), failed to open the line (because Unimodem
won't allow the media type VOICE to be passed for my modem), and failed to set the
play list for this MSP&amp;nbsp;--&amp;nbsp;[&lt;font face="Courier New"&gt;0x80040216&lt;/font&gt;&lt;font face=Verdana&gt;]
is actually a DirectShow error [VFW_E_NOT_FOUND].&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
ITapiTrace Verbose: 0 : Creating ITTAPI instance&lt;br&gt;
ITapiTrace Verbose: 0 : Hooking up connection sink to ITTAPI interface&lt;br&gt;
ITapiTrace Information: 0 : ITTapi::put_EventFilter(0x8001F) hr=0x0&lt;br&gt;
ITapiTrace Error: 0 : COM Hresult 0x80040004 "The MEDIATYPE passed in to this method
was invalid." generated&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;at JulMar.Tapi3.TapiException.ThrowExceptionForHR(Int32 hr)&lt;br&gt;
&amp;nbsp;&amp;nbsp; at JulMar.Tapi3.TTapi.RegisterCallNotifications(ITAddress* pitf, Int16
vbMonitor, Int16 vbOwner, Int32 supportedMediaTypes)&lt;br&gt;
&amp;nbsp;&amp;nbsp; at JulMar.Tapi3.TAddress.Open(TAPIMEDIATYPES supportedMediaTypes)&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 5, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 4, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 3, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 2, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 1, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 0, Terminal=&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiCallNotificationEventArgs: Event=CNE_OWNER,
Call=TCall: 171360625 CS_OFFERING&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiCallStateEventArgs: Call=TCall: 171360625 CS_OFFERING,
State=CS_OFFERING, Cause=CEC_NONE&lt;br&gt;
ITapiTrace Error: 0 : COM Hresult 0x80040216 "" generated&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;at JulMar.Tapi3.TapiException.ThrowExceptionForHR(Int32 hr)&lt;br&gt;
&amp;nbsp;&amp;nbsp; at JulMar.Tapi3.TTerminal.set_MediaPlayList(String[] fileList)&lt;br&gt;
&amp;nbsp;&amp;nbsp; at AnsMachine.AutoAttendantForm.AnswerCall()&lt;br&gt;
&amp;nbsp;&amp;nbsp; at AnsMachine.AutoAttendantForm.OnCallState(Object sender, TapiCallStateEventArgs
e)&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiCallStateEventArgs: Call=TCall: 171360625 CS_DISCONNECTED,
State=CS_DISCONNECTED, Cause=CEC_DISCONNECT_NORMAL&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 5, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 4, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 3, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 2, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 1, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITAddressEvent::get_Terminal failed hr=0x80040055&lt;br&gt;
ITapiTrace Verbose: 0 : Processing TapiAddressChangedEventArgs: Evt=AE_RINGING, Address=DSSP
Line #1 - Address 0, Terminal=&lt;br&gt;
ITapiTrace Error: 0 : ITTapi::Shutdown hr=0x0&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;&lt;strong&gt;&lt;font color=#000000&gt;&lt;/font&gt;&lt;/strong&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,3a275fbf-e292-4017-a783-5b40dc1f0ec7.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
      <category>Debugging</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=4c4e645c-fa73-4d10-855d-99100fa393f4</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,4c4e645c-fa73-4d10-855d-99100fa393f4.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,4c4e645c-fa73-4d10-855d-99100fa393f4.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=4c4e645c-fa73-4d10-855d-99100fa393f4</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <font color="#000000">Matthias Moetje (Tapi MVP) has graciously taken one
of the VB6 Platform SDK samples and ported it to the ITapi3 library and allowed me
to distribute it in the </font>
          <a href="http://www.julmar.com/samples/tapi3wrapper.zip">
            <font color="#000000">Tapi3
Wrapper</font>
          </a>
          <font color="#000000"> sample set.  It allows you to select
an address, place a call on it and then monitor or generate digits.  Great sample
- thanks Matthias!</font>
        </p>
      </body>
      <title>New Digit Monitoring Sample available</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,4c4e645c-fa73-4d10-855d-99100fa393f4.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/07/NewDigitMonitoringSampleAvailable.aspx</link>
      <pubDate>Tue, 07 Mar 2006 23:04:47 GMT</pubDate>
      <description>&lt;p&gt;
&lt;font color=#000000&gt;Matthias Moetje (Tapi&amp;nbsp;MVP)&amp;nbsp;has graciously taken one
of the VB6 Platform SDK samples and ported it to the ITapi3 library and allowed me
to distribute it in the &lt;/font&gt;&lt;a href="http://www.julmar.com/samples/tapi3wrapper.zip"&gt;&lt;font color=#000000&gt;Tapi3
Wrapper&lt;/font&gt;&lt;/a&gt;&lt;font color=#000000&gt; sample set.&amp;nbsp; It allows you to select an
address, place a call on it and then monitor or generate digits.&amp;nbsp; Great sample
- thanks Matthias!&lt;/font&gt;
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,4c4e645c-fa73-4d10-855d-99100fa393f4.aspx</comments>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=b97577a5-a612-4289-b70f-4bd827835c5e</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,b97577a5-a612-4289-b70f-4bd827835c5e.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,b97577a5-a612-4289-b70f-4bd827835c5e.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=b97577a5-a612-4289-b70f-4bd827835c5e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I got an email question today asking about how to write a .WAV file out to an active
call using our TAPI3 wrapper.  It's actually pretty easy to do and it follows
along with the normal SDK method used in C++.  Here's the relevant code (for
the full example, download the <a href="http://www.julmar.com/samples/tapi3wrapper.zip">http://www.julmar.com/samples/tapi3wrapper.zip</a> and
look at the AutoAttendant sample).
</p>
        <p>
First, when a new offering call shows up, get hold of the file playback terminal for
it and set it up to play your .WAV files.  We cannot play the files until the
call is answered, but this will essentially "queue" it up.
</p>
        <font size="2">
          <p>
            <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <font color="#008000">
                  <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                    <font color="#008000">//
Method called when TE_CALLSTATE == OFFERING raised</font>
                    <br />
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
                    <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> AnswerCall()<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
Get the playback terminal from the call</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   try</span><br />
   {<br />
      playbackTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span> activeCall.RequestTerminal(TTerminal.FilePlaybackTerminal, <br />
                  TAPIMEDIATYPES.AUDIO,
TERMINAL_DIRECTION.TD_CAPTURE);<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      if</span> (playbackTerminal
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
      {<br />
         playbackTerminal.MediaPlayList <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">new</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">string</span>[]
{ <font color="#808080">"Hello.wav"</font> };<br />
         activeCall.SelectTerminalOnCall(playbackTerminal);<br />
         activeCall.Answer();<br />
      }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      else</span><br />
      {<br />
         MessageBox.Show(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"Failed
to retrieve playback terminal."</span>);<br />
         activeCall.Disconnect(DISCONNECT_CODE.DC_REJECTED);<br />
      }<br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   catch</span> (TapiException
ex)<br />
   {<br />
   }<br />
}<br /></span>
                </font>
              </span>
            </span>
          </p>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font face="Verdana" color="#000000" size="2">
                <p>
Next, watch for the call media to change indicating we have an active stream for our
terminal.  When that happens, start the playback stream:
</p>
                <p>
                </p>
              </font>
            </span>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
              <font color="#008000">//
Method called when TE_CALLMEDIA is raised<br /></font>
            </span>
          </span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">private</span>
            <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> OnCallMedia(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
TapiCallMediaEventArgs e)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   try</span> <br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      if</span> (activeCall
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span> &amp;&amp;
e.Event == CALL_MEDIA_EVENT.CME_STREAM_ACTIVE &amp;&amp;<br />
            e.Terminal.Direction
== TERMINAL_DIRECTION.TD_CAPTURE &amp;&amp;<br />
            playbackTerminal
!<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
      {<br />
         playbackTerminal.Start();<br />
         SetStatusMessage(<span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4">"File
Playback Terminal started "</span>);<br />
      }<br />
   }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   catch</span> (TapiException
ex)<br />
   {<br />
   }<br />
}<br /></span>
          <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
            <p>
              <font face="Verdana" color="#000000" size="2">Finally, when the file terminal is finished,
close and dispose the stream.  This is done just to cleanup the resources properly:</font>
            </p>
            <p>
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                  <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                    <font color="#008000">//
Method called when TE_FILETERMINAL is raised<br /></font>
                  </span>
                </span>private</span>
              <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">void</span> OnFileTerminal(<span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">object</span> sender,
TapiFileTerminalEventArgs e)<br />
{<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
We are interested in TMS_IDLE because we will un-select playback and </span><br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   //
select recording</span><br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">   if</span> (e.State
== TERMINAL_MEDIA_STATE.TMS_IDLE)<br />
   {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">      if</span> (e.Terminal.Direction
== TERMINAL_DIRECTION.TD_CAPTURE &amp;&amp; playbackTerminal !<span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>)<br />
      {<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         try</span><br />
         {<br /><span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">            //
Remove the playback terminal</span><br />
            activeCall.UnselectTerminalOnCall(playbackTerminal);<br />
            playbackTerminal.Dispose();<br />
            playbackTerminal <span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">=</span><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">null</span>;<br />
         }<br /><span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">         catch</span> (TapiException
ex)<br />
         {<br />
         }<br />
      }<br />
   }<br />
}
</p>
            <p>
              <span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                <span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent">
                  <font color="#000000">
                  </font>
                </span>
              </span>
              <font face="Verdana" size="2">That's
pretty much it -- there's a full sample of this that should work with voice modems
or any streaming-capable TSP.  </font>
            </p>
            <p>
              <font face="Verdana" size="2">
                <strong>Updated: 3/16/05 -- </strong>
              </font>
              <font face="Verdana" size="2">It
doesn't appear to completely work with the H.323 provider; the file terminal gets
connected but apparently never reports an IDLE state and so never gets disconnected
in the above sample.  This appears to be true of the Platform SDK samples as
well.</font>
              <br />
            </p>
          </span>
        </font>
      </body>
      <title>Managing Media Streams with TAPI 3.0</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,b97577a5-a612-4289-b70f-4bd827835c5e.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/06/ManagingMediaStreamsWithTAPI30.aspx</link>
      <pubDate>Mon, 06 Mar 2006 23:02:34 GMT</pubDate>
      <description>&lt;p&gt;
I got an email question today asking about how to write a .WAV file out to an active
call using our TAPI3 wrapper.&amp;nbsp; It's actually pretty easy to do and it follows
along with the normal SDK method used in C++.&amp;nbsp; Here's the relevant code (for
the full example, download the &lt;a href="http://www.julmar.com/samples/tapi3wrapper.zip"&gt;http://www.julmar.com/samples/tapi3wrapper.zip&lt;/a&gt; and
look at the AutoAttendant sample).
&lt;/p&gt;
&lt;p&gt;
First, when a new offering call shows up, get hold of the file playback terminal for
it and set it up to play your .WAV files.&amp;nbsp; We cannot play the files until the
call is answered, but this will essentially "queue" it up.
&lt;/p&gt;
&lt;font size=2&gt; 
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#008000&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#008000&gt;//
Method called when TE_CALLSTATE == OFFERING raised&lt;/font&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; AnswerCall()&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Get the playback terminal from the call&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; activeCall.RequestTerminal(TTerminal.FilePlaybackTerminal,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TAPIMEDIATYPES.AUDIO,
TERMINAL_DIRECTION.TD_CAPTURE);&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (playbackTerminal
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal.MediaPlayList &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;new&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;string&lt;/span&gt;[]
{ &lt;font color=#808080&gt;"Hello.wav"&lt;/font&gt; };&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activeCall.SelectTerminalOnCall(playbackTerminal);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activeCall.Answer();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;else&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;MessageBox.Show(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"Failed
to retrieve playback terminal."&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activeCall.Disconnect(DISCONNECT_CODE.DC_REJECTED);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (TapiException
ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&lt;/span&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font face=Verdana color=#000000 size=2&gt; 
&lt;p&gt;
Next, watch for the call media to change indicating we have an active stream for our
terminal.&amp;nbsp; When that happens, start the playback stream:
&lt;/p&gt;
&lt;p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#008000&gt;//
Method called when TE_CALLMEDIA is raised&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; OnCallMedia(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
TapiCallMediaEventArgs e)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/span&gt;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (activeCall
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt; &amp;amp;&amp;amp;
e.Event == CALL_MEDIA_EVENT.CME_STREAM_ACTIVE &amp;amp;&amp;amp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Terminal.Direction
== TERMINAL_DIRECTION.TD_CAPTURE &amp;amp;&amp;amp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal
!&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal.Start();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;SetStatusMessage(&lt;span style="FONT-SIZE: 11px; COLOR: #666666; FONT-FAMILY: Courier New; BACKGROUND-COLOR: #e4e4e4"&gt;"File
Playback Terminal started "&lt;/span&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (TapiException
ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;br&gt;
&gt;
&lt;/span&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt; 
&lt;p&gt;
&lt;font face=Verdana color=#000000 size=2&gt;Finally, when the file terminal is finished,
close and dispose the stream.&amp;nbsp; This is done just to cleanup the resources properly:&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#008000&gt;//
Method called when TE_FILETERMINAL is raised&lt;br&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;private&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;void&lt;/span&gt; OnFileTerminal(&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;object&lt;/span&gt; sender,
TapiFileTerminalEventArgs e)&lt;br&gt;
{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
We are interested in TMS_IDLE because we will un-select playback and&amp;nbsp;&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
select recording&lt;/span&gt;
&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (e.State
== TERMINAL_MEDIA_STATE.TMS_IDLE)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/span&gt; (e.Terminal.Direction
== TERMINAL_DIRECTION.TD_CAPTURE &amp;amp;&amp;amp; playbackTerminal !&lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: green; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Remove the playback terminal&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;activeCall.UnselectTerminalOnCall(playbackTerminal);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal.Dispose();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;playbackTerminal &lt;span style="FONT-SIZE: 11px; COLOR: red; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;=&lt;/span&gt; &lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;null&lt;/span&gt;;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;catch&lt;/span&gt; (TapiException
ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}
&lt;/p&gt;
&lt;p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;span style="FONT-SIZE: 11px; COLOR: blue; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#000000&gt;&lt;/font&gt;&lt;/span&gt;&lt;/span&gt;&lt;font face=Verdana size=2&gt;That's
pretty much it -- there's a full sample of this that should work with voice modems
or any streaming-capable TSP.&amp;nbsp; &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face=Verdana size=2&gt;&lt;strong&gt;Updated: 3/16/05 -- &lt;/strong&gt;&lt;/font&gt;&lt;font face=Verdana size=2&gt;It
doesn't appear to completely work with the H.323 provider; the file terminal gets
connected but apparently never reports an IDLE state and so never gets disconnected
in the above sample.&amp;nbsp; This appears to be true of the Platform SDK samples as
well.&lt;/font&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;/span&gt;&lt;/font&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,b97577a5-a612-4289-b70f-4bd827835c5e.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=d503a167-04e4-4e88-9218-6deeae20d9ea</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,d503a167-04e4-4e88-9218-6deeae20d9ea.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,d503a167-04e4-4e88-9218-6deeae20d9ea.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=d503a167-04e4-4e88-9218-6deeae20d9ea</wfw:commentRss>
      <title>Wrapping the TAPI 3.0 API with C++/CLI</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,d503a167-04e4-4e88-9218-6deeae20d9ea.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/03/03/WrappingTheTAPI30APIWithCCLI.aspx</link>
      <pubDate>Fri, 03 Mar 2006 18:05:50 GMT</pubDate>
      <description>&lt;p&gt;
New announcement - TAPI3 wrapper for .NET available on our samples page -- &lt;a href="http://www.julmar.com/samples/tapi3wrapper.zip"&gt;http://www.julmar.com/samples/tapi3wrapper.zip&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Recently, I released the ATAPI.NET project into the wild for people to be able to
easily code up .NET applications that utilize TAPI.&amp;nbsp; That assembly is based on
the C API exported from TAPI 2.1 and so uses the older form of TAPI programming.&amp;nbsp;
With Windows 2000, Microsoft released a COM version of TAPI - dubbed TAPI 3.0 that
was designed to allow VB developers to access the telephony API.&amp;nbsp; However, as
I noted in my previous post, Microsoft claims that the object model is too complex
and that there are significant issues with accessing it from managed code.
&lt;/p&gt;
&lt;p&gt;
.NET has a built-in facility to access COM objects, it creates .NET wrappers (called
RCW's) around the COM interfaces and then allows you to call the COM object as if
it were a .NET object.&amp;nbsp; That's great&amp;nbsp;until you need to mesh the COM style
of cleanup (AddRef/Release) with the .NET style (GC).&amp;nbsp; Essentially, the COM object
doesn't get released until the managed wrapper gets collected.&amp;nbsp; In addition,
if you have multiple wrappers for a single interface (TAPI returns the same interface
through different methods), the interface won't be released until &lt;strong&gt;all&lt;/strong&gt; the
wrappers are collected.
&lt;/p&gt;
&lt;p&gt;
Sometimes, this isn't really a problem - so we keep a COM interface alive a little
longer than normal.&amp;nbsp; In TAPI's case however it can be a huge problem because
some TAPI service providers will not let you create new calls unless the&amp;nbsp;existing
call&amp;nbsp;interface has been released - even if it isn't connected to anything.
&lt;/p&gt;
&lt;p&gt;
So, two options exist today:
&lt;/p&gt;
&lt;p&gt;
1) Don't use TAPI 3.x - use TAPI 2.x where you have more control over the underlying
TAPI call handle and can call lineDeallocate yourself.&amp;nbsp; In .NET this means using
some wrapper like ATAPI.NET.&amp;nbsp; If you don't need terminal and stream support,
this is fine.&amp;nbsp; This is what the newsgroups typically will recommend to people.
&lt;/p&gt;
&lt;p&gt;
2) Call Marshal.ReleaseCOMObject on every outstanding interface.&amp;nbsp; Just plain
ugly and extremely error-prone.
&lt;/p&gt;
&lt;p&gt;
Now, a new option exists.&amp;nbsp; I've been in conversations with Matthias Moetje -
one of the TAPI MVPs and went back to my original TAPI3 wrapper which was written
in MC++ (yuck) and ported it to C++/CLI (which, BTW, is very cool).&amp;nbsp; It has almost
everything supported except agents and call center support.&amp;nbsp; It solves the above
problem in a couple of steps:
&lt;/p&gt;
&lt;p&gt;
1) It guarantees that the same interface will match 1:1 with a managed object as long
as the object hasn't been collected yet.&amp;nbsp; This means the object will only have
one holding managed object.&lt;br&gt;
2) It implements IDisposable on most of the&amp;nbsp;wrappers allowing the client to get
rid of interfaces immediately.&lt;br&gt;
3) It "auto-disposes" calls when they hit the disconnected state.&amp;nbsp; This can be
turned on or off depending on need through the &lt;font face="Courier New"&gt;TTapi.AutoDestroyCalls&lt;/font&gt; flag
&lt;/p&gt;
&lt;font size=2&gt; 
&lt;p&gt;
Instead of a Register function, each address has an &lt;font face="Courier New" color=#0000ff&gt;Open&lt;/font&gt; and &lt;font face="Courier New" color=#0000ff&gt;Monitor&lt;/font&gt; method
and a &lt;font face="Courier New" color=#0000ff&gt;Close&lt;/font&gt; method. Since you have to
pass the address in anyway, I moved the function to that level and made it distinct
rather than having you pass in two booleans to indicate intent.
&lt;/p&gt;
&lt;p&gt;
There are some shorthand functions: for example, the &lt;font face="Courier New" color=#0000ff&gt;TCall&lt;/font&gt; object
(which represents ITBasicCallControl, ITCallInfo, et.al.) has a &lt;font face="Courier New" color=#0000ff&gt;SelectDefaultTerminals&lt;/font&gt; method
which enumerates the streams and hooks up the default static/video terminals for each
stream - basically the code that was in every TAPI sample provided by MS. There's
also a &lt;font face="Courier New" color=#0000ff&gt;FindTerminal&lt;/font&gt; method on the TStream
class which will locate a terminal of the proper media type/direction if it exists.
&lt;/p&gt;
&lt;/font&gt; 
&lt;p&gt;
The library itself follows the TAPI3 interfaces pretty closely - except it combines
the various control interfaces together.&amp;nbsp; So for example:
&lt;/p&gt;
&lt;p&gt;
&lt;table class=MsoTableGrid style="BORDER-RIGHT: medium none; BORDER-TOP: medium none; BORDER-LEFT: medium none; BORDER-BOTTOM: medium none; BORDER-COLLAPSE: collapse; mso-border-alt: solid windowtext .5pt; mso-yfti-tbllook: 480; mso-padding-alt: 0in 5.4pt 0in 5.4pt; mso-border-insideh: .5pt solid windowtext; mso-border-insidev: .5pt solid windowtext" cellspacing=0 cellpadding=0 border=1&gt;
&lt;tbody&gt;
&lt;tr style="mso-yfti-irow: 0; mso-yfti-firstrow: yes"&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: black; PADDING-BOTTOM: 0in; BORDER-LEFT: windowtext 1pt solid; WIDTH: 1.2in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt" valign=top width=115&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="COLOR: white"&gt;&lt;font face="Times New Roman"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;Class&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: windowtext 1pt solid; PADDING-LEFT: 5.4pt; BACKGROUND: black; PADDING-BOTTOM: 0in; BORDER-LEFT: #ffffff; WIDTH: 4.95in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt" valign=top width=475&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;b style="mso-bidi-font-weight: normal"&gt;&lt;span style="COLOR: white"&gt;&lt;font face="Times New Roman"&gt;Interfaces&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;&lt;/b&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 1"&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: windowtext 1pt solid; WIDTH: 1.2in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=115&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;TTapi&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ffffff; WIDTH: 4.95in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=475&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-FAMILY: 'Courier New'"&gt;&lt;font color=#000000&gt;ITTapi, ITTapi2&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 2"&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: windowtext 1pt solid; WIDTH: 1.2in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=115&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;TAddress&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ffffff; WIDTH: 4.95in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=475&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;font color=#000000&gt;&lt;span style="FONT-FAMILY: 'Courier New'"&gt;ITAddress, ITAddress2, &lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: 'Courier New'; mso-highlight: white; mso-no-proof: yes"&gt;ITAddressCapabilities&lt;/span&gt;&lt;/font&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;,
ITAddressTranslation, ITLegacyAddressMediaControl, ITLegacyAddressMediaControl2, ITMediaSupport,
ITTerminalSupport&lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr style="mso-yfti-irow: 3; mso-yfti-lastrow: yes"&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: windowtext 1pt solid; WIDTH: 1.2in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=115&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;font color=#000000&gt;&lt;font face="Times New Roman"&gt;TCall&lt;o:p&gt;&lt;/o:p&gt;
&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;td style="BORDER-RIGHT: windowtext 1pt solid; PADDING-RIGHT: 5.4pt; BORDER-TOP: #ffffff; PADDING-LEFT: 5.4pt; PADDING-BOTTOM: 0in; BORDER-LEFT: #ffffff; WIDTH: 4.95in; PADDING-TOP: 0in; BORDER-BOTTOM: windowtext 1pt solid; BACKGROUND-COLOR: transparent; mso-border-alt: solid windowtext .5pt; mso-border-left-alt: solid windowtext .5pt; mso-border-top-alt: solid windowtext .5pt" valign=top width=475&gt;
&lt;p class=MsoNormal style="MARGIN: 0in 0in 0pt"&gt;
&lt;span style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: 'Courier New'; mso-highlight: white; mso-no-proof: yes"&gt;ITCallInfo&lt;/span&gt;&lt;span style="FONT-SIZE: 10pt; COLOR: black; FONT-FAMILY: 'Courier New'; mso-no-proof: yes"&gt;, &lt;span style="BACKGROUND: white; mso-highlight: white"&gt;ITBasicCallControl&lt;/span&gt;, &lt;span style="BACKGROUND: white; mso-highlight: white"&gt;ITBasicCallControl&lt;/span&gt;2, &lt;span style="BACKGROUND: white; mso-highlight: white"&gt;ITStreamControl&lt;/span&gt;, &lt;span style="BACKGROUND: white; mso-highlight: white"&gt;ITLegacyCallMediaControl&lt;/span&gt;, &lt;span style="BACKGROUND: white; mso-highlight: white"&gt;ITLegacyCallMediaControl&lt;/span&gt;2&lt;/span&gt;&lt;span style="FONT-FAMILY: 'Courier New'"&gt;
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;/p&gt;
&lt;p&gt;
In each case, the same properties and methods are exposed by the reference class and
it will do the underlying cast necessary to get to the functionality.&amp;nbsp; The downside
of this, is that if the interface isn't supported, the library must throw an exception
- in this case a &lt;font face="Courier New" color=#0000ff&gt;TapiException&lt;/font&gt; which
holds a string message indicating the failure and an error code (the HRESULT).&amp;nbsp;
The &lt;font face="Courier New" color=#0000ff&gt;TTapi&lt;/font&gt; class exposes the &lt;font face="Courier New"&gt;TE_xxx&lt;/font&gt; events
you generally registered a sink for.
&lt;/p&gt;
&lt;p&gt;
I didn't bother to encapsulate the DirectShow library - instead each of the TAPI wrappers
provides a &lt;font face="Courier New" color=#0000ff&gt;QueryInterface&lt;/font&gt; method which
you can use to get to an interface if necessary.&amp;nbsp; So, for example, if you want
to get to the venerable IVideoWindow interface from DirectShow, you can include an
interop reference to Quartz.DLL and then do the following on the TTerminal object:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;IVideoWindow&lt;/font&gt; videoWindow = thisTerminal.QueryInterface(&lt;font color=#0000ff&gt;typeof&lt;/font&gt;(&lt;font color=#0000ff&gt;IVideoWindow&lt;/font&gt;)) &lt;font color=#0000ff&gt;as&lt;/font&gt; &lt;font color=#0000ff&gt;IVideoWindow&lt;/font&gt;;&lt;br&gt;
&lt;font color=#0000ff&gt;if&lt;/font&gt; (videoWindow != null) { ... }&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So, here's an example of using it - I think it's much cleaner that the comparable
RCW code, and it's thread-aware and works around the general problem of TAPI3 under
.NET through a&amp;nbsp;&lt;font face="Courier New"&gt;Dispose&lt;/font&gt; mechanism and the &lt;font face="Courier New"&gt;TTapi.AutoDestroyCalls&lt;/font&gt; flag.
&lt;/p&gt;
&lt;span style="FONT-SIZE: 11px; COLOR: black; FONT-FAMILY: Courier New; BACKGROUND-COLOR: transparent"&gt;&lt;font color=#0000ff&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt; 
&lt;p&gt;
using
&lt;/font&gt;&lt;font size=2&gt; System;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;using&lt;/font&gt;&lt;font size=2&gt; System.Collections.Generic;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;using&lt;/font&gt;&lt;font size=2&gt; System.Text;&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;using&lt;/font&gt;&lt;font size=2&gt; JulMar.Tapi3;&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt; 
&lt;p&gt;
namespace
&lt;/font&gt;&lt;font size=2&gt; TestTapi&lt;br&gt;
{&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;class&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;Program&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;static&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#0000ff size=2&gt;void&lt;/font&gt;&lt;font size=2&gt; Main(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;string&lt;/font&gt;&lt;font size=2&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&lt;/font&gt;&lt;font color=#008080 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;TTapi&lt;/font&gt;&lt;font size=2&gt; tapi
= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;new&lt;/font&gt;&lt;font size=2&gt; &lt;/font&gt;&lt;font color=#008080 size=2&gt;TTapi&lt;/font&gt;&lt;font size=2&gt;();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;TCall&lt;/font&gt;&lt;font size=2&gt; call
= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;font size=2&gt;; &lt;/font&gt;&lt;font color=#008080 size=2&gt;TAddress&lt;/font&gt;&lt;font size=2&gt; modemAddr
= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;font size=2&gt;;&lt;br&gt;
&lt;/font&gt;&gt;
&lt;p&gt;
&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tapi.Initialize();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tapi.TE_CALLNOTIFICATION += &lt;/font&gt;&lt;font color=#0000ff size=2&gt;delegate&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;object&lt;/font&gt;&lt;font size=2&gt; sender, &lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiCallNotificationEventArgs&lt;/font&gt;&lt;font size=2&gt; e)&amp;nbsp;&amp;nbsp;&lt;br&gt;
&lt;/font&gt;&lt;font size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"New
call {0} detected from {1}"&lt;/font&gt;&lt;font size=2&gt;, e.Call.ToString(), e.Event);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;tapi.TE_CALLSTATE
+= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;delegate&lt;/font&gt;&lt;font size=2&gt;(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;object&lt;/font&gt;&lt;font size=2&gt; sender, &lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiCallStateEventArgs&lt;/font&gt;&lt;font size=2&gt; e)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"{0}:{4}
has changed state to {1} due to {2} - current={3}:{5}"&lt;/font&gt;&lt;font size=2&gt;,&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;e.Call,
e.State, e.Cause, e.Call == call, e.Call.GetHashCode(), (call != &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;font size=2&gt;)
? call.GetHashCode() : 0);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;font size=2&gt; (e.State
== &lt;/font&gt;&lt;font color=#008080 size=2&gt;CALL_STATE&lt;/font&gt;&lt;font size=2&gt;.CS_INPROGRESS
&amp;amp;&amp;amp; e.Call == call)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Dropping
call"&lt;/font&gt;&lt;font size=2&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;e.Call.Disconnect(&lt;/font&gt;&lt;font color=#008080 size=2&gt;DISCONNECT_CODE&lt;/font&gt;&lt;font size=2&gt;.DC_NORMAL);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&lt;/p&gt;
&gt;&lt;font size=2&gt; 
&lt;p&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TAddress&lt;/font&gt;&lt;font size=2&gt; addr &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;font size=2&gt; tapi.Addresses)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;String&lt;/font&gt;&lt;font size=2&gt;.Compare(addr.ServiceProviderName, &lt;/font&gt;&lt;font color=#800000 size=2&gt;"unimdm.tsp"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#0000ff size=2&gt;true&lt;/font&gt;&lt;font size=2&gt;)
== 0 &amp;amp;&amp;amp;&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;addr.QueryMediaType(&lt;/font&gt;&lt;font color=#008080 size=2&gt;TAPIMEDIATYPES&lt;/font&gt;&lt;font size=2&gt;.AUDIO))&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modemAddr
= addr;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&gt;
&lt;p&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if&lt;/font&gt;&lt;font size=2&gt; (modemAddr
!= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;font size=2&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"{0}
= {1} ({3}) [{2}]"&lt;/font&gt;&lt;font size=2&gt;, modemAddr.AddressName, modemAddr.State, modemAddr.ServiceProviderName,
modemAddr.DialableAddress);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;modemAddr.Monitor(&lt;/font&gt;&lt;font color=#008080 size=2&gt;TAPIMEDIATYPES&lt;/font&gt;&lt;font size=2&gt;.AUDIO);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;ConsoleKey&lt;/font&gt;&lt;font size=2&gt; ki
= &lt;/font&gt;&lt;font color=#008080 size=2&gt;ConsoleKey&lt;/font&gt;&lt;font size=2&gt;.A;&gt;
&lt;p&gt;
&lt;/font&gt;&lt;font color=#0000ff size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;while&lt;/font&gt;&lt;font size=2&gt; (ki
!= &lt;/font&gt;&lt;font color=#008080 size=2&gt;ConsoleKey&lt;/font&gt;&lt;font size=2&gt;.Q)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008000 size=2&gt;//
Flip the auto-destroy flag&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;font size=2&gt; (ki
== &lt;/font&gt;&lt;font color=#008080 size=2&gt;ConsoleKey&lt;/font&gt;&lt;font size=2&gt;.D)&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tapi.AutoDestroyCalls
= !tapi.AutoDestroyCalls;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Set
AutoDestroy to {0}"&lt;/font&gt;&lt;font size=2&gt;, tapi.AutoDestroyCalls);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008000 size=2&gt;//
List existing calls&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;font color=#0000ff&gt;else &lt;/font&gt;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;font size=2&gt; (ki
== &lt;/font&gt;&lt;font color=#008080 size=2&gt;ConsoleKey&lt;/font&gt;&lt;font size=2&gt;.L)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;foreach&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TCall&lt;/font&gt;&lt;font size=2&gt; _call &lt;/font&gt;&lt;font color=#0000ff size=2&gt;in&lt;/font&gt;&lt;font size=2&gt; modemAddr.EnumerateCalls())&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Existing
call found: {0}:{1}"&lt;/font&gt;&lt;font size=2&gt;, _call, _call.GetHashCode());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;_call.Dispose(); &lt;/font&gt;&lt;font color=#008000 size=2&gt;//
Go ahead and dump it&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008000 size=2&gt;//
Create a new call&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;else&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;call
= modemAddr.CreateCall(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"5551213"&lt;/font&gt;&lt;font size=2&gt;, &lt;/font&gt;&lt;font color=#008080 size=2&gt;LINEADDRESSTYPES&lt;/font&gt;&lt;font size=2&gt;.PhoneNumber, &lt;/font&gt;&lt;font color=#008080 size=2&gt;TAPIMEDIATYPES&lt;/font&gt;&lt;font size=2&gt;.DATAMODEM);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Created
new call {0}:{1}"&lt;/font&gt;&lt;font size=2&gt;, call, call.GetHashCode());&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;try&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008000 size=2&gt;//
This will fail if existing call interface is still around (i.e. not disposed)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font size=2&gt;call.Connect(&lt;/font&gt;&lt;font color=#0000ff size=2&gt;false&lt;/font&gt;&lt;font size=2&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;catch&lt;/font&gt;&lt;font size=2&gt; (&lt;/font&gt;&lt;font color=#008080 size=2&gt;TapiException&lt;/font&gt;&lt;font size=2&gt; ex)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(ex.Message);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"Press
a key to try another call.. Q to quit"&lt;/font&gt;&lt;font size=2&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ki
= &lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.ReadKey().Key;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&gt;
&lt;p&gt;
&lt;font color=#008000&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//&amp;nbsp;This
will destroy any&amp;nbsp;outstanding interfaces&lt;br&gt;
&lt;/font&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;tapi.Shutdown();
&lt;/p&gt;
&lt;p&gt;
&lt;/font&gt;&lt;font color=#008000 size=2&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;//
Call should be disposed here.. state will be CS_UNKNOWN&amp;nbsp;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#0000ff size=2&gt;if&lt;/font&gt;&lt;font size=2&gt; (call
!= &lt;/font&gt;&lt;font color=#0000ff size=2&gt;null&lt;/font&gt;&lt;font size=2&gt;)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;/font&gt;&lt;font color=#008080 size=2&gt;Console&lt;/font&gt;&lt;font size=2&gt;.WriteLine(&lt;/font&gt;&lt;font color=#800000 size=2&gt;"{0}
{1}"&lt;/font&gt;&lt;font size=2&gt;, call, call.CallState);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br&gt;
}&lt;/font&gt;
&lt;br&gt;
&lt;/span&gt;&amp;nbsp;&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,d503a167-04e4-4e88-9218-6deeae20d9ea.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
    <item>
      <trackback:ping>http://www.julmar.com/blog/mark/Trackback.aspx?guid=712cc7bb-42fe-4ecf-909e-1c5ea3c725c9</trackback:ping>
      <pingback:server>http://www.julmar.com/blog/mark/pingback.aspx</pingback:server>
      <pingback:target>http://www.julmar.com/blog/mark/PermaLink,guid,712cc7bb-42fe-4ecf-909e-1c5ea3c725c9.aspx</pingback:target>
      <dc:creator>Mark</dc:creator>
      <wfw:comment>http://www.julmar.com/blog/mark/CommentView,guid,712cc7bb-42fe-4ecf-909e-1c5ea3c725c9.aspx</wfw:comment>
      <wfw:commentRss>http://www.julmar.com/blog/mark/SyndicationService.asmx/GetEntryCommentsRss?guid=712cc7bb-42fe-4ecf-909e-1c5ea3c725c9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Ok, ok so it's been a while.  I've been very busy with two tasks -- first, I
spent the last few weeks doing a Guerrilla .NET for <a href="http://www.develop.com">DevelopMentor</a> with <a href="http://www.dotnetconsult.co.uk/weblog/">Rich
Blewitt</a>.  We had a blast together and it was great to hang out with him. 
I also spent a day sitting in on DM's new C++/CLI class being taught by the very capable
Marcus Heege - incredible stuff which every C++ guy on the Microsoft platform should
get into..
</p>
        <p>
The other thing I've been working with is resurrecting an old project of mine - ATAPI
which was originally setup to wrap the TAPI 2.x API in an "easy to use" set of C++
classes.  I'd ported it to .NET a few years ago but was not really happy with
the results.  I had the chance to revisit it because of a client's requirement
to integrate TAPI into their .NET platform code.  So, I spent a couple of weeks
working on the codebase again under .NET 2.0 and this time around I'm pretty pleased
with the architecture.  I wanted something very easy to use, and I think
I've achieved that even though it isn't a complete wrapper.  
</p>
        <p>
For example, to walk through all the lines and dump out the device classes available -
you can simply do this:
</p>
        <p>
          <font face="Courier New">
            <font color="#0000ff">using</font> System;<br /><font color="#0000ff">using</font> System.Collections.Generic;<br /><font color="#0000ff">using</font> System.Text;<br /><font color="#0000ff">using</font> JulMar.Atapi;</font>
        </p>
        <p>
          <font face="Courier New">
            <font color="#0000ff">namespace</font> EnumDevices<br />
{<br />
    <font color="#0000ff">class</font> Program<br />
    {<br />
        <font color="#0000ff">static void</font> Main(<font color="#0000ff">string</font>[]
args)<br />
        {<br />
            TapiManager mgr
= <font color="#0000ff">new</font> TapiManager(<font color="#800080">"EnumDevices"</font>);<br />
            mgr.Initialize(); <font color="#008000">//
Start up Tapi</font></font>
        </p>
        <p>
          <font face="Courier New">            <font color="#0000ff">foreach</font> (TapiLine
line <font color="#0000ff">in</font> mgr.Lines)<br />
            {<br />
                <font color="#0000ff">foreach</font> (string
s in line.Capabilities.AvailableDeviceClasses)<br />
                   
Console.WriteLine<font color="#800080">("{0} - {1}"</font>, line.Name, s);<br />
            }            
<br />
            mgr.Shutdown();<br />
        }<br />
    }<br />
}</font>
        </p>
        <p>
Cool huh?
</p>
        <p>
So.. why not use the TAPI3 COM API you ask?  Well, as it turns out, it doesn't
work that well with the RCW infrastructure in .NET -- check out <a href="http://support.microsoft.com/kb/841712/en-us">http://support.microsoft.com/kb/841712/en-us</a> where
Microsoft basically says "TAPI3 is too complicated".. like I needed someone to tell
me that..
</p>
        <p>
The ATAPI.NET stuff is available from JulMar's download area - you can get it
along with a sample program from <a href="http://www.julmar.com/samples/atapinet.zip">http://www.julmar.com/samples/atapinet.zip</a>.
</p>
        <p>
enjoy.
</p>
      </body>
      <title>ATAPI for .NET 2.0</title>
      <guid isPermaLink="false">http://www.julmar.com/blog/mark/PermaLink,guid,712cc7bb-42fe-4ecf-909e-1c5ea3c725c9.aspx</guid>
      <link>http://www.julmar.com/blog/mark/2006/02/15/ATAPIForNET20.aspx</link>
      <pubDate>Wed, 15 Feb 2006 19:20:58 GMT</pubDate>
      <description>&lt;p&gt;
Ok, ok so it's been a while.&amp;nbsp; I've been very busy with two tasks -- first, I
spent the last few weeks doing a Guerrilla .NET for &lt;a href="http://www.develop.com"&gt;DevelopMentor&lt;/a&gt;&amp;nbsp;with &lt;a href="http://www.dotnetconsult.co.uk/weblog/"&gt;Rich
Blewitt&lt;/a&gt;.&amp;nbsp; We had a blast together and it was great to hang out with him.&amp;nbsp;
I also spent a day sitting in on DM's new C++/CLI class being taught by the very capable
Marcus Heege - incredible stuff which every C++ guy on the Microsoft platform should
get into..
&lt;/p&gt;
&lt;p&gt;
The other thing I've been working with is resurrecting an old project of mine - ATAPI
which was originally setup to wrap the TAPI 2.x API in an "easy to use" set of C++
classes.&amp;nbsp; I'd ported it to .NET a few years ago but was not really happy with
the results.&amp;nbsp; I had the chance to revisit it because of a client's requirement
to integrate TAPI into their .NET platform code.&amp;nbsp; So, I spent a couple of weeks
working on the codebase again under .NET 2.0 and this time around I'm pretty pleased
with the architecture.&amp;nbsp; I wanted&amp;nbsp;something very easy to use, and I think
I've achieved that even though it isn't&amp;nbsp;a complete wrapper.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
For example, to walk through all the lines and dump out the device classes available&amp;nbsp;-
you can simply do this:
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;using&lt;/font&gt; System;&lt;br&gt;
&lt;font color=#0000ff&gt;using&lt;/font&gt; System.Collections.Generic;&lt;br&gt;
&lt;font color=#0000ff&gt;using&lt;/font&gt; System.Text;&lt;br&gt;
&lt;font color=#0000ff&gt;using&lt;/font&gt; JulMar.Atapi;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&lt;font color=#0000ff&gt;namespace&lt;/font&gt; EnumDevices&lt;br&gt;
{&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;class&lt;/font&gt; Program&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;static void&lt;/font&gt; Main(&lt;font color=#0000ff&gt;string&lt;/font&gt;[]
args)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; TapiManager mgr
= &lt;font color=#0000ff&gt;new&lt;/font&gt; TapiManager(&lt;font color=#800080&gt;"EnumDevices"&lt;/font&gt;);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mgr.Initialize(); &lt;font color=#008000&gt;//
Start up Tapi&lt;/font&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;foreach&lt;/font&gt; (TapiLine
line &lt;font color=#0000ff&gt;in&lt;/font&gt; mgr.Lines)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;font color=#0000ff&gt;foreach&lt;/font&gt; (string
s in line.Capabilities.AvailableDeviceClasses)&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
Console.WriteLine&lt;font color=#800080&gt;("{0} - {1}"&lt;/font&gt;, line.Name, s);&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; mgr.Shutdown();&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;
}&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
Cool huh?
&lt;/p&gt;
&lt;p&gt;
So.. why not use the TAPI3 COM API you ask?&amp;nbsp; Well, as it turns out, it doesn't
work that well with the RCW infrastructure in .NET -- check out &lt;a href="http://support.microsoft.com/kb/841712/en-us"&gt;http://support.microsoft.com/kb/841712/en-us&lt;/a&gt;&amp;nbsp;where
Microsoft basically says "TAPI3 is too complicated".. like I needed someone to tell
me that..
&lt;/p&gt;
&lt;p&gt;
The ATAPI.NET stuff is available from JulMar's download area - you can&amp;nbsp;get it
along with a sample program from &lt;a href="http://www.julmar.com/samples/atapinet.zip"&gt;http://www.julmar.com/samples/atapinet.zip&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
enjoy.
&lt;/p&gt;</description>
      <comments>http://www.julmar.com/blog/mark/CommentView,guid,712cc7bb-42fe-4ecf-909e-1c5ea3c725c9.aspx</comments>
      <category>Code</category>
      <category>Tapi</category>
    </item>
  </channel>
</rss>