Solved

how to check call status

Posted on 2001-08-11
20
445 Views
Last Modified: 2013-11-20
Dear Experts
using TAPI function Calls i have successfully dialed a phone call. But i am still unable to get the status of a call that is whether the phone is busy at the recievers end  etc.
plz help me out .....plzzzzzzzzzzz
:)
donot worry about the points they can be increased.
thanx
0
Comment
Question by:trium
20 Comments
 
LVL 32

Expert Comment

by:jhance
Comment Utility
Do you have the book, Windows Telephony Programming by Chris Sells?  If not, and you are doing TAPI programming, you're going to want it.
0
 

Author Comment

by:trium
Comment Utility
dear jhance
i donot have that book ... whatever i had studied is from MSDN. tell me how to check the stsus of a call .. i am Working In VC(Visual C++)
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
>> donot worry about the points they can be increased.
The points *do* matter.  50 pts means you are in no big hurry to get an answer and that you don't expect an expert to spend any extra effort to dig in an generate and test a functional code snippet.

Here's the brief answer:

Your TAPI callback fn will get LINE_CALLSTATE messages.  For instance, if it gets LINECALLSTATE_DIALTONE, then it has gone off hook and detected dialtone.  If it gets LINECALLSTATE_PROCEEDING, then it has sent the tones and is waiting for ringback, etc..

-- Dan
0
 

Author Comment

by:trium
Comment Utility
hey !!Rollins

thanx for the response but the functions u r telling are to check the status of our telephone line instead i want to check the line status of the dialed party's telephone such as it is busy or ready or now the phone has been hooked (lifted) by the dialed party.

REGARDS.

~~~~~~~~~~~~~~~~~~~~~~>>TRIUM<<~~~~~~~~~~~~~~~~~~~~~~~
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Refer to MSDN coverage of TAPI and the cascade of documentation starting at:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tapi/hh/tapi22/tapi22portal_3l45.asp

in particular, this lists the status constants:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/tapi/hh/tapi22/constnts_6t0z.asp

There are lots of call state statuse messages that your callback will recieve, including:

LINECALLSTATE_BUSY
LINECALLSTATE_CONNECTED

-- Dan
0
 

Author Comment

by:trium
Comment Utility
Dear DanRollins

i used the lineGetCallStatus function. but it doesn't return zero value
 showing its unsuccessfull completion .plz guide me what's wrong with
this code.

//after successfully making a call using lineMakeCall function

LINECALLSTATUS* lcs = new LINECALLSTATUS;
lcs->dwTotalSize=sizeof(LINECALLSTATUS);


lineGetCallStatus(hCall,lcs);
// hCall is the handle of the call returned by the lineMakeCall function

0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
if it is returning non-zero, then there is an error in a parameter to the lineGetStatus() call.

Expected return value is LINEERR_STRUCTURETOOSMALL.  TAPI if full of calls in which you need to pass a buffer of unknown size.  There might be some variable-length stuff at the end of a LINECALLSTATUS structure.  A typical way to allocate structures for TAPI is something like:

int nSizeToTry= sizeof(LINECALLSTATUS) + 900;

LPLINECALLSTATUS prCS= (LPLINECALLSTATUS)malloc(nSizeToTry);
prCS->dwTotalSize= nSizeToTry;

//-------- you could loop and repeat...
long nErr= ::lineGetCallStatus( hCall, prCS );
if (nErr== LINEERR_STRUCTURETOOSMALL ) {
    nSizeToTry = prCS->dwNeededSize+100;
    free(prCS);
    prCS= (LPLINECALLSTATUS)malloc(nSizeToTry);
    prCS->dwTotalSize= nSizeToTry;
    nErr= ::lineGetCallStatus( hCall, prCS );
}

-==-=-=-=-=-
if the error is other than LINEERR_STRUCTURETOOSMALL, then you need to figure out what error it is.  Otherwise, you won't know what error is occuring.  In general, the best to learn what error is occuring is to examine the error code that is returned from a call.  Error codes are our friends.

-- Dan
0
 

Author Comment

by:trium
Comment Utility
Dear Dan

the error generated by the lineGetcallStatus() is
"LINEERR_INVALCALLHANDLE"
i.e invalid call handle.
why the call handle is invalid, although the "lineMakeCall() function returns
positive identifier showin' its successfull completion.
how can i get the valid call handle.
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Perhaps you are not using the value that was returned in tn the lphCall variable that you used in lineMakeCall.  Eg,

HCALL hCall;

long nRet= ::lineMakeCall( hLine, &hCall, ... );

More likely, you are not waiting for the call to complete.  As stated in the dox... lineMakeCall is an asynchronous fn.  It returns immediately.  It is not meaningful to check status until the call has been completed.

When you use ::lineInitialize(...), you set the address of your TAPICallBack fn.  Since you have not mentioned it in any of your posts, it is likely that you have not implemented this critical function.  You will get a LINE_REPLY msg there that will indicate when the asynchronous lineMakeCall has completed.

-- Dan
0
 

Author Comment

by:trium
Comment Utility

i'm using the same call handle returned by lineMakeCall()
function

here's my code


#define TAPI_VERSION_1_0      0x00010004

HCALL hCall;
HLINE hLine;

LONG retcode;

LPCSTR lpszAppName="Dialer";
HINSTANCE hInstance=NULL;
DWORD NumDevs,i;

DWORD  RetApiVersion;        
DWORD lpdwAPIVersion=0x00020002;                                  

LINEEXTENSIONID lpExtensionID;  

LINEINITIALIZEEXPARAMS ep;
 ep.dwTotalSize=sizeof(LINEINITIALIZEEXPARAMS);
 ep.dwOptions=LINEINITIALIZEEXOPTION_USEHIDDENWINDOW ;
 
  retcode=lineInitializeEx(
  &LineHandle,                            
 
  AfxGetInstanceHandle(),
  &lpLineCallbf,                        
 lpszAppName,                        
 &NumDevs,
 
  &lpdwAPIVersion,
  &ep);
 
   
//   LINE NEGOTIATION
   
     for(i=0;i<NumDevs;i++)
     {//start for

retcode = lineNegotiateAPIVersion(LineHandle,i,
TAPI_VERSION_1_0 , lpdwAPIVersion, &RetApiVersion,
&lpExtensionID);


lineOpen( LineHandle, i, &hLine,  RetApiVersion, 0,
                     
                      0,
                      //dwCbi,
               LINECALLPRIVILEGE_MONITOR ,LINEMEDIAMODE_AUTOMATEDVOICE,

                NULL );

}


l=lineMakeCall( hLine, &hCall,"4840440",0,NULL);
 //----------------------------

int nSizeToTry= sizeof(LINECALLSTATUS) + 900;

LPLINECALLSTATUS prCS= (LPLINECALLSTATUS)malloc(nSizeToTry);
prCS->dwTotalSize= nSizeToTry;

lineGetCallStatus(hCall,prCS);


and here's my call back function


void CALLBACK lpLineCallbf(
     
  DWORD hDevice,
     
  DWORD dwMsg,              
  DWORD dwCallbackInstance,  
  DWORD dwParam1,            
  DWORD dwParam2,            
  DWORD dwParam3)
{

switch (dwParam1)
{

     case LINECALLSTATE_DIALTONE:

     {
         
          MessageBox(hWnd,"dialtone","BUSY",MB_OK);
           break;
            }


        case LINECALLSTATE_PROCEEDING:

     {
         
          MessageBox(hWnd,"proceeding","BUSY",MB_OK);


           break;
            }

  case LINECALLSTATE_BUSY:

     {

        MessageBox(hWnd,"line is busy1","BUSY",MB_OK);
           break;
            }

 
       }//end switch

       }//end callback


i get all the messages except line busy message .why?????












0
What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

 

Author Comment

by:trium
Comment Utility
Dear Dan
after calling a lineMakeCall() function i give a sleep of 2 seconds to
 wait for the completion of call.so now lineGetCallStatus() function
returns zero.
but still it doesn't give  the busy status of the dialed number.
i'm checkin' the busy status like this

// after lineMakeCall() function

Sleep(2000);


int nSizeToTry= sizeof(LINECALLSTATUS) + 900;

LPLINECALLSTATUS prCS= (LPLINECALLSTATUS)malloc(nSizeToTry);
prCS->dwTotalSize= nSizeToTry;

lineGetCallStatus(hCall,prCS);

if(prCS->dwCallState==LINECALLSTATE_BUSY)
------//whatever i wanna do
also the callback function iz not reportin' the busy status, although it's
reportin' other status like "dialing, proceeding ,connected.etc."

0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Your callback fn is written poorly.  You need to check the second parameter (named dwMsg) and do different things depending upon if it is LINE_CALLSTATE or LINE_REPLY, etc.

I use the Line_REPLY message and save the dwParam2 (that gives me the last status recieved from the ::lineMakeCall fn.  When its dwParam1 is the same as the positive value returned from ::lineMakeCall (the replyID) then that callback is indicating the status of the asynchronous call to ::lineMakeCall.  

Anyway, I suppose that in a very simplified system, you could sleep for a while before calling ::lineMakeCall then call ::lineGetStatus.  But 2 seconds is not nearly long enough for your modem to recognize a busy signal.  Try waiting for 30 seconds.

It is also possible that your modem is set up incorrectly so that it does not inform the system when it recognoizes a busy signal.  

But it is far more likely that you are not waiting long enough -- and more correctly, not handling the callback correctly so that you know how long to wait.

-- Dan
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Hi trium,
Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 
LVL 49

Accepted Solution

by:
DanRollins earned 150 total points
Comment Utility
Hi trium,
Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 

Author Comment

by:trium
Comment Utility
Dear Dan

i was checkin' the second parametre(dwMsg).in the code the parameter
(dwParam1) was written by mistake.
c my callback function now

void CALLBACK lpLineCallbf(
     
  DWORD hDevice,
  DWORD dwMsg,              
  DWORD dwCallbackInstance,  
  DWORD dwParam1,            
  DWORD dwParam2,            
  DWORD dwParam3)
{
switch(dwMsg)
     {
case LINE_REPLY:

     switch(dwParam2)
             {
  case LINECALLSTATE_BUSY:

     {

        AfxMessageBox("line is busy");
           break;
         }
           
              }
     }//end switch

}

i get the busy message in both the cases wether it iz busy or not
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Could be a modem problem.  Make sure that Windows knows your modem by manufacturer and model (not as "standard model").

It could also be related to your PBX system -- I get false "line is busy" messages from my modem at the office when the "call waiting" thingy makes a tone upon going off-hook.

-- Dan
0
 

Author Comment

by:trium
Comment Utility
so do you think my code is alright?????

-----trium
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
In my own LINE_REPLY handler all I do is set a flag indicating that the request has finished.  To detect busy etc., I check for dwMsg of LINE_CALLSTATE and then switch of dwp1, like so:

    switch (dwP1) {
          case LINECALLSTATE_DIALTONE:   UpdateStatus("Dial Tone",         0,1); OutputDebugString("Dial Tone\n");                break;
          case LINECALLSTATE_DIALING:    UpdateStatus("Dialing Call",      1,1); OutputDebugString("Dialing\n");                  break;
          case LINECALLSTATE_PROCEEDING: UpdateStatus("Call is Proceeding",1,1); OutputDebugString("Proceeding\n");               break;
          case LINECALLSTATE_RINGBACK:   UpdateStatus("RingBack",          1,1); OutputDebugString("RingBack\n");                 break;
          case LINECALLSTATE_BUSY:       UpdateStatus("Line is busy",      1,1); OutputDebugString("Line busy, shutting down\n");          
               m_sErrMsg= "Line is BUSY";
               HangupCall();
          break;
          case LINECALLSTATE_IDLE:        UpdateStatus("Line is idle",      1,1); OutputDebugString("Line idle\n");
               HangupCall();
          break;
          case LINECALLSTATE_SPECIALINFO: UpdateStatus( "Special Info, probably couldn't dial number",0,1);    OutputDebugString( "Special Info, probably couldn't dial number\n");
               HangupCall();
          break;

          case LINECALLSTATE_DISCONNECTED:
               switch (dwP2) {
                    case LINEDISCONNECTMODE_NORMAL:       psReason= "Remote Party Disconnected";    break;
                    case LINEDISCONNECTMODE_UNKNOWN:      psReason= "Disconnected: Unknown reason"; break;
                    case LINEDISCONNECTMODE_REJECT:       psReason= "Remote Party rejected call";   break;
                    case LINEDISCONNECTMODE_PICKUP:       psReason= "Local phone picked up";        break;
                    case LINEDISCONNECTMODE_FORWARDED:    psReason= "Forwarded";                    break;
                    case LINEDISCONNECTMODE_BUSY:         psReason= "BUSY SIGNAL";                  break;
                    case LINEDISCONNECTMODE_NOANSWER:     psReason= "NO ANSWER";                    break;
                    case LINEDISCONNECTMODE_BADADDRESS:   psReason= "Bad Address";                  break;
                    case LINEDISCONNECTMODE_UNREACHABLE:  psReason= "Unreachable";                  break;
                    case LINEDISCONNECTMODE_CONGESTION:   psReason= "Congestion";                   break;
                    case LINEDISCONNECTMODE_INCOMPATIBLE: psReason= "Incompatible";                 break;
                    case LINEDISCONNECTMODE_UNAVAIL:      psReason= "Unavail";                      break;
                    case LINEDISCONNECTMODE_NODIALTONE:   psReason= "NO DIALTONE";                  break;
                    default:                              psReason= "LINECALLSTATE; Bad Reason";    break;
               }
               m_sErrMsg= psReason;
               UpdateStatus(psReason,1,1);
               OutputDebugString(psReason);
               OutputDebugString("\n");
               HangupCall();
          break;
     
          case LINECALLSTATE_CONNECTED:  // CONNECTED!!!
               if ( m_fConnected ) {      // handle only the first one of these
                    break;
               }
               OnConnect();
               m_fConnected= TRUE;
          break;
     }
}
0
 
LVL 49

Expert Comment

by:DanRollins
Comment Utility
Hi trium,
Do you have any additional questions?  Do any comments need clarification?

-- Dan
0
 
LVL 1

Expert Comment

by:Computer101
Comment Utility
Comment from DanRollins accepted as answer.

Thank you
Computer101
Community Support Moderator
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
This video gives you a great overview about bandwidth monitoring with SNMP and WMI with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're looking for how to monitor bandwidth using netflow or packet s…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now