Making a Call with TAPI

< BACK  NEXT >
[oR]
  • Open a device line using the function lineOpen.

  • Translate the telephone number from canonical form (including international dial-in number and area code) to a dialable form (taking into account the user's current location).

  • Call lineMakeCall to make the call that connects asynchronously.

  • Provide a lineCallbackFunc function to receive notifications.

  • Close the call by calling lineDrop, lineDeallocateCall and lineClose.

Opening a Line

The TAPI lineOpen function opens a line device ready for making a call. The line device identifier and the negotiated TAPI version are passed to the function, which returns a line device handle (Table 11.5).

Table 11.5. lineOpen Opens a line device ready for making a call
lineOpen
HLINEAPP hLineApp HLINEAPP handle returned from calling lineInitialize.
DWORD dwDeviceID Line device identifier to negotiate version for. Between 0 and dwNum-Lines 1 returned from lineInitialize.
LPHLINE lphLine Pointer to an HLINE variable that receives a handle to the open line device.
DWORD dwAPIVersion Negotiated TAPI version number returned from lineNegotiateAPI-Version.
DWORD dwExtVersion Unsupported, pass as zero.
DWORD dwCallbackInstance Application-defined value passed to the lineCallbackFunc function with notification messages.
DWORD dwPrivileges Incoming call privileges. Pass LINECALLPRIVILEGE_NONE if incoming calls are not required or supported.
DWORD dwMediaModes Media modes supported by application when receiving calls. Pass 0 if incoming calls are not supported.
LPLINECALLPARAMS const lpCallParams CALLPARAMS structure specifying how the call should be made. Passing NULL specifies that a default call will be made.
LONG Return Value Zero for success, or a LINERR_ value indicating an error. These errors are defined in tapi.h.

Listing 11.3a shows the first part of the function MakeCall that negotiates the TAPI version number and calls lineOpen to obtain a HLINE handle through which the call will be made.

Listing 11.3a Function MakeCall Opening a line
 HLINE g_hLine = NULL; HCALL g_hCall = NULL; void MakeCall(DWORD dwLineId, LPTSTR szPhoneNumber) {   DWORD dwTAPIVersion, dwReturn;   LPLINETRANSLATEOUTPUT lpTransOutput = NULL;   DWORD dwSizeOfTransOut = sizeof (LINETRANSLATEOUTPUT);   TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE + 1];   cout   _T("Dialing: ")   szPhoneNumber   endl;   dwTAPIVersion = NegotiateTAPIVersion(dwLineId);   if(dwTAPIVersion == 0)     return;   if (dwReturn = lineOpen(     g_hLineApp,  // Usage handle for TAPI     dwLineId,    // Cannot use the LINEMAPPER value     &g_hLine,                // Line handle     dwTAPIVersion,           // API version number     0,          // Must set to zero for Windows CE     0,                   // No data passed back     // Can only make an outgoing call     LINECALLPRIVILEGE_NONE,     0,              // Media mode     NULL))          // Must set to NULL for Windows CE   {     cout   _T("Could not open line: ")   dwReturn;     return;   }   // Remainder of program follows. 

Translating a Telephone Number

Telephone numbers are usually stored in canonical format, and this may include the international dial-in number and area code. Canonical format telephone numbers must first be translated to a dialable format before making the call. This translation takes into account the configured current location of the user and determines if a local, long distance, or international call needs to be made. It is important to call lineTranslateAddress even if you have a correctly formatted telephone number for the current location. Some line devices place a "P" or "T" before the telephone number to indicate pulse or tone dialing when translating the number, and without this the call will fail. The function lineTranslateAddress (Table 11.6) is passed the TAPI usage handle, device line identifier, a negotiated TAPI version, and the phone number to be translated.

The code in Listing 11.3b is a continuation of the MakeCall function started in Listing 11.3a. The LINETRANSLATEOUTPUT is another structure that has variable size depending on the amount of information appended after the structure as defined in tapi.h. The LINETRANSLATEOUTPUT structure lpTransOutput must be allocated to a sufficient size to receive the translated telephone number. In the first iteration of the "do" loop, the allocation is made to the size of LINETRANSLATEOUTPUT, with the dwTotalSize member being set to this size. On returning from calling lineTranslateAddress the dwNeededSize member will contain the actual required size of the LINETRANSLATEOUPUT structure. If this is greater than the size provided, the structure is reallocated and the function lineTranslateAddress called again.

Table 11.6. lineTranslateAddress Translates a phone number from canonical to dialable form
lineTranslateAddress
HLINEAPP hLineApp HLINEAPP handle returned from calling lineInitialize.
DWORD dwDeviceID Line device identifier to negotiate version for. Between 0 and dwNumLines 1 returned from lineInitialize.
DWORD dwAPIVersion Negotiated TAPI version number returned from lineNegotiate-APIVersion.
LPCTSTR lpszAddressIn Telephone number to be translated.
DWORD dwCard Unsupported, pass as zero.
DWORD dwTranslateOptions Translate options constants. Examples are
LINETRANSLATEOPTION_CANCELCALLWAITING to cancel call waiting.
LINETRANSLATEOPTION_FORCELOCAL to force a local call.
LPLINETRANSLATEOUTPUT lpTranslateOutput Pointer to a LINETRANSLATEOUTPUT structure to receive the translated telephone number.
LONG Return Value Zero for success, or a LINERR_ value indicating an error. These errors are defined in tapi.h.

Listing 11.3b Function MakeCall Translating phone number
 // Function MakeCall continued // Call translate address before dialing. do {   // Allocate memory for lpTransOutput.   if (!(lpTransOutput = (LPLINETRANSLATEOUTPUT)       LocalAlloc(LPTR, dwSizeOfTransOut)))     return;   lpTransOutput->dwTotalSize = dwSizeOfTransOut;   if (dwReturn = lineTranslateAddress (     g_hLineApp,      // Usage handle for TAPI     dwLineId,        // Line device identifier     dwTAPIVersion,   // Highest TAPI version     szPhoneNumber,   // Address to be translated     0,               // Must be 0 for Windows CE     0,               // No associated operations     lpTransOutput))  // Translated address   {     LocalFree(lpTransOutput);     return;   }   if (lpTransOutput->dwNeededSize <=       lpTransOutput->dwTotalSize)     break;   else   {     dwSizeOfTransOut =       lpTransOutput->dwNeededSize;     LocalFree (lpTransOutput);     lpTransOutput = NULL;   } } while (TRUE); // Save the translated phone number for dialing. wcscpy(szDialablePhoneNum,   (LPTSTR) ((LPBYTE) lpTransOutput +     lpTransOutput->dwDialableStringOffset)); cout   _T("Translated Number: ")       szDialablePhoneNum   endl; // Remainder of program follows. 

Once a successful call to lineTranslateAddress has been made, the dwDialableStringOffset member is used to locate the translated telephone number at the end of the lpTransOutput structure. The telephone number is copied into the string buffer szDialablePhoneNum.

 wcscpy(szDialablePhoneNum,   (LPTSTR) ((LPBYTE) lpTransOutput +     lpTransOutput->dwDialableStringOffset)); 

Now that a translated telephone number has been obtained, the call can be made. Notice that a telephone number is translated using the line device identifier and not a handle to an open line device. This means that the telephone numbers can be translated without first opening the line device.

Making the Call

The function lineMakeCall (Table 11.7) makes a call through a handle to an opened line device using a translated telephone number. The function returns a handle to the call in a HCALL variable. The call is made asynchronously that is, lineMakeCall will return before the dialing has completed. An application can monitor the various stages of making the call (such as dialing and then making the connection) through the callback function set when TAPI was initialized with a call to lineInitialize. The structure of this callback function is described in the next section. You should note that the callback function is called using the same thread that is used to initialize TAPI. If this is the same thread used to call lineMakeCall, take care in blocking the thread you might end up blocking the calls to the callback function as well.

Table 11.7. lineMakeCall Dials the specified number through an open line device
lineMakeCall
HLINE hLine Handle to an open line obtained by calling lineOpen.
LPHCALL lphCall Pointer to an HCALL variable in which the call handle is returned.
LPCTSTR lpszDestAddress Telephone number to be dialed.
DWORD dwCountryCode Country code to use, or 0 for the default.
LPLINECALLPARAMS const lpCallParams LINECALLPARAMS structure specifying how the call is to be made. If NULL, a default call is made.
LONG Return Value Zero for success, or a LINERR_ value indicating an error. These errors are defined in tapi.h.

Listing 11.3c Function MakeCall Dialing the number
   // Make the phone call.   dwReturn = lineMakeCall(     g_hLine,               // handle to open line     &g_hCall,              // return handle to call     szDialablePhoneNum,    // phone number to dial     0,                     // default country code     NULL);                 // call parameters   if(dwReturn < 0)     cout   _T("Could not make call")        dwReturn  endl;   else if(dwReturn >= 0)     cout   _T("Dialing asynchronously")   endl; } void Listing11_3() {   DWORD dwNumLines;   if(!(dwNumLines = InitializeTAPI()))     return;   // insert telephone number here in place of xxxxxx   MakeCall(6, _T("xxxxxx ")); } 

The code in Listing 11.3c completes the code in MakeCall. A function call is made to lineMakeCall to call the number and receive back a handle to the new call in g_hCall.

Line Callback Function

An application initializing TAPI with lineInitialize should provide a callback function like that shown in Listing 11.3d. The function is passed a device handle and message type in dwMsg. When making a call, the dwMsg value will contain the value LINE_CALLSTATE, and these are generally the only messages an application making straightforward calls using TAPI will be interested in.

When the dwMsg variable has the value LINE_CALLSTATE, the dwParam1 parameter contains a reason code for the notification, such as LINECALLSTATE_DIALING. These constants are defined in tapi.h. The most important reason code is LINECALLSTATE_CONNECTED once this has been received an application can start sending and receiving data through the connection.

Listing 11.3d lineCallbackFunc
 VOID FAR PASCAL lineCallbackFunc(DWORD hDevice,     DWORD dwMsg, DWORD dwCallbackInstance,     DWORD dwParam1, DWORD dwParam2, DWORD dwParam3) {   // only interested in LINE_CALLSTATE messages   if(dwMsg != LINE_CALLSTATE)     return;   cout   _T("LINE_CALLSTATE: ");   // dwParam1 is the specific LINE_CALLSTATE   // change occurring   switch (dwParam1)     {     case LINECALLSTATE_IDLE:       cout   _T("Idle");       break;     case LINECALLSTATE_DIALTONE:       cout   _T("Dial tone");       break;     case LINECALLSTATE_DIALING:       cout   _T("Dialing");       break;     case LINECALLSTATE_PROCEEDING:       cout   _T("Dialing has completed");       break;     case LINECALLSTATE_RINGBACK:       cout   _T("Ring back");       break;     case LINECALLSTATE_CONNECTED:       cout   _T("Connected");       break;     case LINECALLSTATE_BUSY:       cout   _T("Busy");       break;     case LINECALLSTATE_DISCONNECTED:       switch (dwParam2)       {       case LINEDISCONNECTMODE_NORMAL:         cout            _T("Normal disconnect");         break;       case LINEDISCONNECTMODE_UNKNOWN:         cout            _T("Unknown reason");         break;       case LINEDISCONNECTMODE_REJECT:         cout            _T("Remote Party rejected");         break;       case LINEDISCONNECTMODE_BUSY:         cout            _T("Remote busy");         break;       default:         cout            _T("Disconnect: Other reason")             dwParam2;         break;       Listing11_4();  // close call and line       }       break;     default:       cout   _T("Other notification")           dwParam1;   }   cout  endl; } 

The reason code LINECALLSTATE_DISCONNECTED is sent when a call is terminated, and the dwParam2 parameter contains a reason code for the disconnection. A common disconnect code is LINEDISCONNECTMODE_BUSY, indicating that the telephone number being called is engaged. In the event of a LINECALLSTATE_DISCONNECTED reason code being received, an application should close the relevant TAPI handles associated with the call. In Listing 11.3d this is done by calling the function Listing11_4, as described in the next section.

Shutting Down a Call

Your application or the party being called can terminate a call. To drop a call, your application should call the lineDrop function to drop the call, and then lineDeallocateCall to free any resources associated with the call and close the HCALL handle (Listing 11.4). At this point, the open line device can be used to make another call, or lineClose can be called to close the HLINE handle.

Listing 11.4 Shutting down a call
 void Listing11_4() {   lineDrop(g_hCall, // call to drop     NULL,           // no data to be sent on drop     0);             // length of data to be sent   lineDeallocateCall(g_hCall);   g_hCall = NULL;   lineClose(g_hLine);   g_hLine = NULL;   ShutdownTAPI(); } 

In the event of the call being terminated by the other party, the call-back function will receive a LINECALLSTATE_DISCONNECTED notification as described in the previous section.


< BACK  NEXT >


Windows CE 3. 0 Application Programming
Windows CE 3.0: Application Programming (Prentice Hall Series on Microsoft Technologies)
ISBN: 0130255920
EAN: 2147483647
Year: 2002
Pages: 181

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net