Opening a Line and Making a Phone Call

When an application has initiated and negotiated the API, the application needs to verify if the line is usable and ready for dialing out. The application can do this by checking the values filled into the LINEDEVCAPS structure by calling the lineGetDevCaps function.

To open a line device for any purpose, the application calls the lineOpen function. The lineOpen function opens the specified line device and returns a line handle to the opened line device. This line handle is used in subsequent operations on the line device. Later, when the application is finished using the line device, it can close it with lineClose.

Before it makes a telephone call, the application needs to open the line. The lineOpen function opens and the lineClose function closes a specific TAPI device.

The lineOpen function specifies:

To place a call, the application must call the lineMakeCall function using the LINECALLPARAMS structure. TAPI sends LINE_CALLSTATE messages to indicate the progress of the call. For example, LINE_CALLSTATE indicates states of connection, dialing, proceeding, and so on. The messages vary depending on the type of call and the service provided. The application should not be designed to one type or one special sequence of call states.

The lineMakeCall function has the following parameters:

After the lineMakeCall function successfully sets up the call, the application receives a LINE_REPLY message. The callback function receives the message. The LINE_REPLY message also informs the application that the call handle returned by lineMakeCall is valid.

When the application has opened the line successfully, it receives a handle to the line. The application can then use that line to make outbound calls.

The following code example shows how to open a line and make an outbound call.

VOID MakePhoneCall (LPCTSTR lpszPhoneNum)
{
  DWORD dwReturn,
        dwSizeOfTransOut = sizeof (LINETRANSLATEOUTPUT),
        dwSizeOfCallParams = sizeof (LINECALLPARAMS);

  LPLINECALLPARAMS lpCallParams = NULL;
  LPLINETRANSLATEOUTPUT lpTransOutput = NULL;
  
  TCHAR szDialablePhoneNum[TAPIMAXDESTADDRESSSIZE + 1] = {'\0'};

  // Initialize g_MakeCallRequestID.
  g_MakeCallRequestID = 0;
  
  // Open the current line.
  if (dwReturn = lineOpen (
          g_hLineApp,                 // Usage handle for TAPI
          g_dwCurrentLineID,          // Cannot use the LINEMAPPER value
          &g_CurrentLineInfo.hLine,   // Line handle
          g_CurrentLineInfo.dwAPIVersion, 
                                      // API version number
          0,                          // Must set to zero for Windows CE
          0,                          // No data passed back 
          LINECALLPRIVILEGE_NONE,     // Can only make an outgoing call
          0,                          // Media mode 
          NULL))                      // Must set to NULL for Windows CE
  {
    goto exit;
  }
  
  // Call translate address before dialing.
  do
  {
    // Allocate memory for lpTransOutput.
    if (!(lpTransOutput = (LPLINETRANSLATEOUTPUT) LocalAlloc (
                                                    LPTR,  
                                                    dwSizeOfTransOut)))
    {
      goto exit;
    }

    lpTransOutput->dwTotalSize = dwSizeOfTransOut;

    if (dwReturn = lineTranslateAddress (
          g_hLineApp,               // Usage handle for TAPI
          g_dwCurrentLineID,        // Line device identifier 
          g_CurrentLineInfo.dwAPIVersion, 
                                    // Highest TAPI version supported 
          lpszPhoneNum,             // Address to be translated
          0,                        // Must be 0 for Windows CE
          0,                        // No associated operations 
          lpTransOutput))           // Result of the address translation
    {
      goto exit;
    }
    
    if (lpTransOutput->dwNeededSize <= lpTransOutput->dwTotalSize)
      break; 
    else
    {
      dwSizeOfTransOut = lpTransOutput->dwNeededSize;
      LocalFree (lpTransOutput);
      lpTransOutput = NULL;
    }

  } while (TRUE);
     
  dwSizeOfCallParams += lpTransOutput->dwDisplayableStringSize;
  
  if (!(lpCallParams = (LPLINECALLPARAMS) LocalAlloc (
                                                  LPTR, 
                                                  dwSizeOfCallParams)))
  {
    goto exit;
  }

  // Set the call parameters.
  lpCallParams->dwTotalSize = dwSizeOfCallParams;
  lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
  lpCallParams->dwMediaMode = LINEMEDIAMODE_DATAMODEM; 
  lpCallParams->dwCallParamFlags = LINECALLPARAMFLAGS_IDLE;
  lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
  lpCallParams->dwAddressID = g_dwCurrentLineAddr;
  lpCallParams->dwDisplayableAddressSize = 
                                lpTransOutput->dwDisplayableStringSize;
  lpCallParams->dwDisplayableAddressOffset = sizeof (LINECALLPARAMS);

  // Save the translated phone number for dialing.
  lstrcpy (szDialablePhoneNum, (LPTSTR)((LPSTR)lpTransOutput + \
           lpTransOutput->dwDisplayableStringOffset));

  // Set the cursor as the wait cursor.
  SetCursor (LoadCursor (NULL, IDC_WAIT));

  // Make the phone call. lpCallParams should be NULL if the default 
  // call setup parameters are requested.
  g_MakeCallRequestID = lineMakeCall (g_CurrentLineInfo.hLine,            
                                      &g_hCall,         
                                      szDialablePhoneNum, 
                                      0, 
                                      lpCallParams);    

  // Set the cursor back to an arrow.
  SetCursor (0);

  if (g_MakeCallRequestID > 0) 
  {
    g_bCurrentLineAvail = FALSE;

    DialogBoxParam (g_hInst, 
                    MAKEINTRESOURCE(IDD_DIALING), 

                    g_hwndMain, 
                    (DLGPROC) DialingProc, 0);
  }
  else 
  {
    ErrorBox (TEXT("Failed in making the phone call, function")
              TEXT("\nlineMakeCall failed."));
    CurrentLineClose ();
  }

exit :

  if (lpCallParams)
    LocalFree (lpCallParams);
  
  if (lpTransOutput)
    LocalFree (lpTransOutput);

  // If the make call did not succeed but the line was opened, 
  // then close it.
  if ((g_MakeCallRequestID <= 0) && (g_CurrentLineInfo.hLine))
    CurrentLineClose ();

  return;
}