home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Network Support Encyclopedia 96-1
/
novell-nsepro-1996-1-cd2.iso
/
download
/
netware
/
tmonit.exe
/
TMONITOR.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-01-06
|
10KB
|
342 lines
/****************************************************************************
** File: TMONITOR.C
**
** Desc: Sample telephony program
**
** This NetWare Telephony Services program acts as an NLM. It monitors
** a device for the delivered event, (calls being made), and reports them.
** It asks the user if they want to attempt to answer the call or not.
** At this time, it reports both incoming and outgoing calls.
**
** This program is written for Watcom C/C++ 10.0a, using the NLM SDK.
**
**
** DISCLAIMER
**
** Novell, Inc. makes no representations or warranties with respect to
** any NetWare software, and specifically disclaims any express or
** implied warranties of merchantability, title, or fitness for a
** particular purpose.
**
** Distribution of any NetWare software is forbidden without the
** express written consent of Novell, Inc. Further, Novell reserves
** the right to discontinue distribution of any NetWare software.
**
** Novell is not responsible for lost profits or revenue, loss of use
** of the software, loss of data, costs of re-creating lost data, the
** cost of any substitute equipment or program, or claims by any party
** other than you. Novell strongly recommends a backup be made before
** any software is installed. Technical support for this software
** may be provided at the discretion of Novell.
**
** Programmers:
**
** Ini Who Firm
** -----------------------------------------------------------------------
** KVW Kevin V White Novell Developer Support.
**
** History:
**
** When Who What
** -----------------------------------------------------------------------
** 1/5/95 kvw wrote code
** 1/6/95 kvw added comments, disclaimer
*/
/****************************************************************************
** Include headers, macros, function prototypes, etc.
*/
/*------------------------------------------------------------------------
** ANSI
*/
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <errno.h>
#include <process.h>
#include <signal.h>
/*------------------------------------------------------------------------
** Telephony Services
*/
#include <acs.h>
#include <csta.h>
/*------------------------------------------------------------------------
** Just in case...
*/
#ifndef BOOL
#define BOOL int
#endif
/*------------------------------------------------------------------------
** Stack size for the thread
*/
#define MY_STACK_SIZE 16384
/*------------------------------------------------------------------------
** These are for thread control, so the NLM and thread can synchronize
** close down.
*/
BOOL NLM_exiting=FALSE;
BOOL NLM_mainDone=FALSE;
int NLM_threadCnt=0;
/*------------------------------------------------------------------------
** Global variables (ok, slap my wrist) used for getting events, and the
** stream handle.
*/
ACSHandle_t acsHandle;
InvokeID_t invokeID;
DeviceID_t deviceToMonitor;
CSTAEvent_t eventBuffer;
unsigned short eventBufferSize;
unsigned short numEvents;
/*------------------------------------------------------------------------
** This function is actually a thread. It basicly sits in a poll loop
** getting all events from the queue, searching for delivered events.
*/
void monitorFunc(void *arg)
{
char ch;
RetCode_t rCode;
CSTAMonitorFilter_t monitorFilter;
CSTAMonitorCrossRefID_t monitorCrossRefID=0;
/*------------------------------------------------------
** Just do this so I don't get a compiler warning for
** not using the argument
*/
arg=arg;
NLM_threadCnt++;
/*------------------------------------------------------
** I am only going to monitor for delivered events.
*/
monitorFilter.call=~CF_DELIVERED;
/*------------------------------------------------------
** Start the device type monitor.
*/
rCode=cstaMonitorDevice(acsHandle,invokeID,&deviceToMonitor,&monitorFilter,NULL);
/*------------------------------------------------------
** If successful, enter event poll loop.
*/
if(rCode>=0)
{
printf("\n\nWaiting for a call...");
/*---------------------------------------------------
** This flag gets set when SigTerm occurs, and the
** NLM tries to shutdown
*/
while(!NLM_exiting)
{
eventBufferSize=sizeof(CSTAEvent_t);
/*------------------------------------------------
** Get an event, and check its type
*/
rCode=acsGetEventPoll(acsHandle,&eventBuffer,&eventBufferSize,NULL,&numEvents);
if(rCode==ACSPOSITIVE_ACK)
{
switch(eventBuffer.eventHeader.eventType)
{
/*-----------------------------------------------
** This is _probably_ the first event we'll get on
** our new monitor. However, we can't guarantee
** that, so I handle it here in the switch.
** We need the CrossRefID for use when we shut down
** the monitor.
*/
case CSTA_MONITOR_CONF:
monitorCrossRefID=
eventBuffer.event.cstaConfirmation.u.monitorStart.monitorCrossRefID;
break;
/*-----------------------------------------------
** When we get a delivered event, we are going
** to print out information on the screen and
** ask the user if they want to answer it.
*/
case CSTA_DELIVERED:
printf("\nAlerting:%s Calling:%s Called:%s",
eventBuffer.event.cstaUnsolicited.u.delivered.alertingDevice.deviceID,
eventBuffer.event.cstaUnsolicited.u.delivered.callingDevice.deviceID,
eventBuffer.event.cstaUnsolicited.u.delivered.calledDevice.deviceID);
/*--------------------------------------------
** User wants to answer the call. We'll try,
** but it's not guaranteed. They might be on
** the other line, and since I'm not tracking
** other active calls, I don't have a callID
** to put the other call on hold first.
** If the cstaAnswerCall function fails, we
** don't do anything about it.
*/
printf("\nTry to answer call? (y/n)");
ch=getch();
switch(ch)
{
case 'y':
case 'Y':
cstaAnswerCall(acsHandle,invokeID,
&eventBuffer.event.cstaUnsolicited.u.delivered.connection,
NULL);
break;
}
printf("\n\nWaiting for a call...");
break;
}
}
/*------------------------------------------------
** Give back some CPU time.
*/
ThreadSwitchWithDelay();
}
/*---------------------------------------------------
** We got here only because of NLM_exiting. So, we
** shut down the monitor.
*/
if(monitorCrossRefID)
rCode=cstaMonitorStop(acsHandle,invokeID,monitorCrossRefID,NULL);
}
NLM_threadCnt--;
}
/*---------------------------------------------------------
** This is used to replace the handler for SigTerm, which is
** triggered when the NLM is unloaded.
*/
void mySigTerm(int sigType)
{
/*------------------------------------------------------
** Just use this so we don't get a compiler error for
** not using the argument.
*/
sigType=sigType;
/*------------------------------------------------------
** All we do is set NLM_exiting, so the threads all know
** we wnat to exit. Then, check the flags set when the
** threads actually are ready to exit.
*/
NLM_exiting=TRUE;
while((!NLM_mainDone)||(NLM_threadCnt))
ThreadSwitchWithDelay();
return;
}
void main(void)
{
int cCode;
char myStack[MY_STACK_SIZE];
InvokeIDType_t invokeIDType;
StreamType_t streamType;
ServerID_t serverID;
LoginID_t loginID;
Passwd_t password;
AppName_t appName;
Level_t acsLevel;
Version_t acsVersion;
unsigned short sendQSize,sendExtraBufs;
unsigned short recvQSize,recvExtraBufs;
PrivateData_t *privateData;
RetCode_t rCode;
/*------------------------------------------------------
** Set up my SigTerm handler for exiting the NLM.
*/
signal(SIGTERM,mySigTerm);
SetAutoScreenDestructionMode(TRUE);
invokeIDType=LIB_GEN_ID;
invokeID=0;
streamType=ST_CSTA;
strcpy(serverID,"ATT#G3_SWITCH#CSTA#KVWHITETEL");
printf("\nEnter your user name:");
scanf("%s",loginID);
printf("\nEnter your password:");
scanf("%s",password);
printf("\nEnter the extension to monitor:");
scanf("%s",deviceToMonitor);
strcpy(appName,"monitor");
acsLevel=ACS_LEVEL1;
strcpy(acsVersion,CSTA_API_VERSION);
sendQSize=sendExtraBufs=recvQSize=recvExtraBufs=15;
privateData=NULL;
/*------------------------------------------------------
** Open the stream with the data the user entered.
*/
rCode=acsOpenStream(&acsHandle,invokeIDType,invokeID,streamType,&serverID,&loginID,&password,
&appName,acsLevel,&acsVersion,sendQSize,sendExtraBufs,recvQSize,recvExtraBufs,privateData);
if(rCode<0)
{
printf("acsOpenStream failure...");
goto done;
}
else
{
printf("acsOpenStream success...");
invokeID=rCode;
}
eventBufferSize=sizeof(CSTAEvent_t);
rCode=acsGetEventBlock(acsHandle,&eventBuffer,&eventBufferSize,privateData,&numEvents);
if(rCode==ACSPOSITIVE_ACK)
{
if(eventBuffer.eventHeader.eventType==ACS_OPEN_STREAM_CONF)
{
printf("event received for acsOpenStream");
}
else
{
printf("event type is incorrect on acsOpenStream");
goto done;
}
}
else
{
printf("acsGetEventBlock failure");
goto done;
}
/*------------------------------------------------------
** If the stream was successfully opened, we start a new
** thread to monitor the device for delivered events.
*/
cCode=BeginThread(monitorFunc,myStack,MY_STACK_SIZE,NULL);
if(cCode==EFAILURE)
goto closeStream;
/*------------------------------------------------------
** Just sit and wait for the NLM to exit. The other thread
** does all the work while this one just sits back and
** relaxes. Of course, we give the CPU time back.
*/
while((NLM_threadCnt) || (!NLM_exiting))
{
ThreadSwitchWithDelay();
}
/*------------------------------------------------------
** close the stream
*/
closeStream:
acsAbortStream(acsHandle,NULL);
done:
NLM_mainDone=TRUE;
return;
}