Using TAPI

The TApdTapiDevice component uses TAPI (Telephony API).  This component is used for recording or playing wave files in voice applications when the EnableVoice property is set to True.  This article is designed to clarify how the connection is handled and what events are generated when using TAPI to establish a connection. 

TAPI Pro And Con

TAPI has the advantage of selecting the modem by name instead of by port number.  TAPI should also give you a pre-configured modem, based on the modem's INF settings.  TAPI will also let you co-exist with other TAPI applications using the port.  For example, if you have another TAPI application waiting for calls, you can open that port with TAPI to send a fax without having to shut down the other application.

The downside is that the modem's INF could be faulty (usually updating the modem drivers will fix this).  There is also the need to add a few more lines of code to open the TAPI device (ConfigAndOpen and wait for the OnTapiPortOpen) and to close it (CancelCall and wait for the OnTapiPortClose).

TAPI Dial Method

TApdTapiDevice generates OnTapiStatus events during the dialing process.  If a modem connection is not established, an OnTapiFail event is generated.  If a connection is established, an OnTapiConnect event is generated, the associated TApdComPort is opened, and the OnTapiPortOpen event is generated. 

Once the connection is established, the TApdTapiDevice is no longer directly used.  At this point the TApdComPort is in control until the call is terminated.  The application should not simply close the TApdComPort because that would not disconnect the modem connection.  Instead, the application must direct TAPI to close the connection by calling the CancelCall method of ApdTapiDevice.  The TApdTapiDevice then breaks the connection with the modem, closes the associated TApdComPort, and generates the OnTapiPortClose event. 

If a dial attempt fails due to a busy signal or other error, TApdTapiDevice can try the call again.  This is controlled by the MaxAttempts Property, which determines how many times Dial tries the call, and RetryWait, which determines how long (in seconds) Dial waits before retrying a failed call.


TAPI AutoAnswer

The TApdTapiDevice.AutoAnswer method tells TAPI that we are interested in accepting incoming calls.  Once we answer a call, TAPI does not notify us that a new call is being received until we call AutoAnswer again.  So, to answer the next call, you need to call AutoAnswer again. 

To terminate the call, use the CancelCall method and the OnTapiFail event will be generated.   You want to call your AutoAnswer again in the OnTapiFail event.  You'll also want to set EnableVoice before calling AutoAnswer.  If there was no connection established, then you donít want to CancelCall because OnTapiFail will not fire and AutoAnswer will not be called.

Detecting Hang-up

TAPI does not provide a consistent notification when a voice connection is
terminated by the other side (often, TAPI can not detect this condition at
all).  Your best bet is to watch the OnTapiLog event for the lineDrop log
event.  Usually, a voice connection is terminated from the local side,
either based on silence detection (inactivity on the line) or when your call
termination conditions have been met. 

Hearing from customers time and time again about how the OnTapiFail does not always fire after a CancelCall.  As a backup plan you might set a flag and a timer on in the OnConnect event to let you know there was a call.  The timer is there in case the OnTapiFail event does not fire, then call AutoAnswer in the timer code. 

It's basically the same thing as why you can't tell when the remote actually answers.  The modem and TAPI can't tell when voice energy enters or leaves the line.  TAPI will usually (not always) detect a remote hang-up after about 60 seconds of dead time, and you should get the OnTapiFail event.  This isn't consistent between modems or TAPI versions.  I've seen some modem/TAPI combinations that wouldn't generate any events, so you'd have to use a timer to detect when nothing has happened for a while.  The TapiTest project on would give you a good feel for what
events and messages are generated when the remote disconnects and how to handle the different messages to suit your needs.

TAPI Failure Codes

It all boils down to how the TAPI responses are generated and handled.  If the call terminates (either normally or abnormally) we get the TAPI failure message and generate the OnTapiFail event.  You can get TAPI's reason for the failure in the FailureCode property from that event.  TAPI's reason for the failure may not always be accurate, but it's what we have to work with.  The TAPI failure codes are in AdTUtil.pas, look at the LineDisconnectMode_ and LineErr_ constants. 

You can also get some failure notifications from the OnTapiLog event including TapiBusy.  CancelCall can take a few seconds (TAPI does some things with the modem and port, etc).  Make sure you are waiting for the OnTapiPortClose event (and/or the OnTapiFail).


This site is not affiliated, endorsed, or otherwise associated with the entity formerly known as TurboPower Software. The owners and maintainers of were merely meager employees of the aforementioned organization, providing this site out of the pure goodness of their collective hearts. Logo

Last updated: July 22, 2003.