I've been experimenting on TAPI programming. I'm trying to write an application that can answer incoming calls. When I run the code below, the application just waits. So when I call my telephone, the application fails to answer the incoming call. Does anyone know what I'm doing wrong here?
#include <tapi.h>
#include <windows.h>
#include <iostream.h>
#include <stdio.h>
//Global declarations
LONG lres;
HLINEAPP phLineApp;
HLINE hLine;
HCALL hCall;
HANDLE eventReply;
HANDLE tapiEvent;
HANDLE eventThread;
DWORD dwNumDevs;
DWORD dwApiVer = 0x00020002;
DWORD dwLowApiVer = 0x00010004;
DWORD dwDeviceId;
DWORD mediaMode;
DWORD dwNegApiVer;
DWORD i;
DWORD tapiMessage;
LINEINITIALIZEEXPARAMS lineParam;
LINEEXTENSIONID extId;
LINEDEVCAPS *lDevCap;
bool boolres = FALSE;
//Tapi Event Thread and Routines
DWORD WINAPI tapiThread(LPVOID lpThreadParam)
{
while(TRUE)
{
DWORD dwStatus = WaitForSingleObject(tapiEvent, 10);
if(dwStatus == WAIT_OBJECT_0)
{
LINEMESSAGE lMessage;
lres = lineGetMessage(phLineApp, &lMessage,0);
if(lres == 0) cout << "Got line message\n";
else cout << "Error : Cannot get line message\n";
if(lMessage.dwParam1==LINECALLSTATE_OFFERING)
{
hCall = (HCALL)lMessage.hDevice;
tapiMessage = LINECALLSTATE_OFFERING;
SetEvent(eventReply);
break;
}
}
}
return 0;
}
//Main
int main()
{
lineParam.dwTotalSize = sizeof(LINEINITIALIZEEXPARAMS);
lineParam.dwOptions = LINEINITIALIZEEXOPTION_USEEVENT;
//Create Event
eventReply = CreateEvent(NULL, FALSE, FALSE, NULL);
if(eventReply != NULL) cout << "Event created\n";
else cout << "Error : Can't create event\n";
//Initialize TAPI
lres = lineInitializeEx(&phLineApp, NULL, NULL, "TAPI Test",
&dwNumDevs, &dwApiVer, &lineParam);
if(lres == 0) cout << "TAPI initialized\n";
else cout << "Error : TAPI not initialized\n";
//Get event handle
tapiEvent = lineParam.Handles.hEvent;
//Event monitoring
DWORD dwThreadId, dwThrdParam = 1;
eventThread = CreateThread(NULL, 0, tapiThread, &dwThrdParam, 0, &dwThreadId);
if(eventThread == NULL) cout << "Error : Can't create thread\n" << GetLastError() << endl;
//Select valid line device
for(i=0; i<dwNumDevs; i++)
{
//Negotiate Api Version
lres = lineNegotiateAPIVersion(phLineApp, i, dwLowApiVer, dwApiVer, &dwNegApiVer, &extId);
if(lres == 0)
{
cout << "API version negotiated\n";
//Allocate sufficient memory
lDevCap = (LINEDEVCAPS *)malloc(sizeof(LINEDEVCAPS)+1024);
if(lDevCap == NULL) cout << "Can't allocate memory\n";
lDevCap->dwTotalSize = sizeof(LINEDEVCAPS)+1024;
do
{
//Get device capabilites
lres = lineGetDevCaps(phLineApp, i, dwNegApiVer, 0, lDevCap);
if(lres == 0) cout << "Got device capabilities\n";
if(lres != 0) cout << "Error : Cannot get device capabilites\n";
if(lDevCap->dwNeededSize > lDevCap->dwTotalSize)
lDevCap = (LINEDEVCAPS *)realloc(lDevCap, lDevCap->dwNeededSize);
else boolres = TRUE;
}
while(!boolres);
if(lDevCap->dwMediaModes & (LINEMEDIAMODE_INTERACTIVEVOICE|LINEMEDIAMODE_DATAMODEM))
{
dwDeviceId = i;
mediaMode = lDevCap->dwMediaModes;
cout << "Line " << dwDeviceId << " selected\n";
}
else cout <<"Error : No line is selected\n";
}
else cout << "Error : API version not negotiated\n";
}
//Open the selected line
lres = lineOpen(phLineApp, dwDeviceId, &hLine, dwNegApiVer, 0, 1,
LINECALLPRIVILEGE_OWNER, mediaMode, NULL);
if(lres == 0) cout << "Line is opened\n";
else cout << "Error : Line not opened\n";
//Event notification
lres = lineSetStatusMessages(hLine, 0x1ffffff, 0);
if(lres == 0) cout << "Success : lineSetStatusMessages\n";
else cout << "Error : Can't set status messages\n";
//Wait for notification
while(1)
{
WaitForSingleObject(eventReply, INFINITE);
if(tapiMessage == LINECALLSTATE_OFFERING)
{
cout << "Answering call.....\n";
lres = lineAnswer(hCall, NULL, 0);
if(lres == 0) cout << "Call answered\n";
else cout << "Error : Can't answer call\n";
break;
}
}
return 0;
}
by: DanRollinsPosted on 2003-01-20 at 01:50:00ID: 7759970
Are you certain that you are working with TAPI 2 or later? The event thingy won't work otherwise. I have only used the callback mechanism and I have not tried to answer the phone, only make outgoing calls.
If you don't mind experimenting, I'd suggest trying to setup for the callback.
-- Dan