In the Asynchronous model, after the application issues an asynchronous function, it uses the sr_waitevt( ) function to wait for events on Dialogic devices.
Choose the Asynchronous model for any application that:
Asynchronous Model Advantages
Asynchronous Model Disadvantages
Asynchronous Model Programming Notes
|
Get Dialogic device handle for the current event. | |
|
Get event type for the current event. | |
|
Get a pointer to additional data for the current event. | |
|
Get the number of bytes of additional data that are pointed to by sr_getevtdatap( ). |
Asynchronous Model ExampleAn example of the Asynchronous model is shown below:
/*
* This asynchronous mode sample application was designed to work with
* D/41ESC, VFX/40ESC, LSI/81SC, LSI/161SC and D/160SC-LS boards only.
* It was compiled using MS-VC++.
* It cycles through channels going offhook, dialing a digit string,
* going onhook. This is repeated until the user hits a keyboard key.
* The thread to monitor the keyboard is peripheral to the main application
* and the asynchronous programming mode and may be replaced with any other
* mechanism the user may desire.
*/
/* C includes */
#include <stdio.h>
#include <process.h>
#include <string.h>
#include <conio.h>
#include <windows.h>
#include <winbase.h>
/* Dialogic includes */
#include <srllib.h>
#include <dxxxlib.h>
#include <sctools.h> /* needed for nr_scroute() declaration */
/* Defines */
#define MAXCHAN 4 /* maximum number of voice channels in system */
#define USEREVT_KEYBOARD 1 /* User defined keyboard event */
/* This may be expanded to contain other information such as state */
typedef struct dx_info {
int chdev;
} DX_INFO;
/* Globals */
DX_INFO dxinfo[MAXCHAN+1];
int Kbhit_flag = 0;
/* Prototypes */
int main();
DWORD WINAPI keyboard_monitor(LPVOID);
int process(int,int);
/****************************************************************
* NAME : int main()
* DESCRIPTION : prepare screen for output, create keyboard monitor
* : thread and process asynchronous events received
* INPUT : none
* OUTPUT : none
* RETURNS : 0 on success; 1 if a failure was encountered
* CAUTIONS : none
****************************************************************/
int main()
{
int numchan;
char channame[20];
HANDLE threadHdl;
DWORD ThrdID;
int evtdev, evttype;
/* show application's title */
printf("Asynchronous Mode Sample Application - hit any key to exit...\n");
/* Create a thread for monitoring keyboard input */
threadHdl = (HANDLE)_beginthreadex(NULL,
0,
keyboard_monitor,
NULL,
0,
&ThrdID);
if (threadHdl == (HANDLE) -1 ) {
printf("Error creating keyboard monitor thread -- exiting\n");
return(1);
}
/* Initial processing for MAXCHANS */
for (numchan=1;numchan<=MAXCHAN;numchan++) {
/* build name of voice channel */
sprintf(channame, "dxxxB%dC%d", ((numchan-1) / 4) + 1,
((numchan -1)% 4) + 1);
/* open voice channel */
if ((dxinfo[numchan].chdev = dx_open(channame, 0)) == -1) {
/* Perform system error processing */
return(1);
}
/* Store numchan as USERCONTEXT for this device */
sr_setparm(dxinfo[numchan].chdev,SR_USERCONTEXT,&numchan);
printf( "Voice channel opened (%s)\n", ATDV_NAMEP(dxinfo[numchan].chdev));
/* route voice channel to it's analog front end */
if (nr_scroute(dxinfo[numchan].chdev,
SC_VOX,
dxinfo[numchan].chdev,
SC_LSI,
SC_FULLDUP) == -1) {
printf("FAILED: nr_scroute(%s): %s (error #%d)\n",
ATDV_NAMEP(dxinfo[numchan].chdev),
ATDV_ERRMSGP(dxinfo[numchan].chdev),
ATDV_LASTERR(dxinfo[numchan].chdev));
return(1);
}
printf( "Voice channel connected to analog front end\n");
/* Start the application by putting the channel in onhook state */
if (dx_sethook(dxinfo[numchan].chdev,DX_ONHOOK,EV_ASYNC) == -1) {
printf("FAILED: dx_sethook(%s): %s (error #%d)\n",
ATDV_NAMEP(dxinfo[numchan].chdev),
ATDV_ERRMSGP(dxinfo[numchan].chdev),
ATDV_LASTERR(dxinfo[numchan].chdev));
return(1);
}
}
/* While no keyboard input, keep cycling through functions */
while (1) {
/* Wait for events */
sr_waitevt(-1);
evtdev = sr_getevtdev();
evttype = sr_getevttype();
if ((evtdev == SRL_DEVICE) && (evttype == USEREVT_KEYBOARD))
break;
if (process(evtdev, evttype) != 0)
break;
}
/* Close all voice devices before exiting */
for (numchan=1;numchan<=MAXCHAN;numchan++) {
dx_close(dxinfo[numchan].chdev);
}
/* Wait here until thread exits */
if (WaitForMultipleObjects(1, &threadHdl, TRUE, INFINITE) == WAIT_FAILED) {
printf("ERROR: Failed WaitForMultipleObjects(): error = %ld\n",
GetLastError());
}
return(0);
}
/***************************************************************************
* NAME: DWORD WINAPI keyboard_monitor( LPVOID argp )
* DESCRIPTION: Wait for keyboard input
* INPUT: LPVOID argp
* OUTPUT: None
* RETURNS: none
* CAUTIONS: None
***************************************************************************/
DWORD WINAPI keyboard_monitor( LPVOID argp )
{
getch();
sr_putevt(SRL_DEVICE,USEREVT_KEYBOARD,0,NULL,0);
return(0);
}
/***************************************************************************
* NAME: int process( eventdev, event )
* DESCRIPTION: Do the next function depending on the Event Received
* INPUT: int eventdev; - Device on which event was received
* int event; - Event being processed
* OUTPUT: None
* RETURNS: New Channel State
* CAUTIONS: None
***************************************************************************/
int process( eventdev, event )
int eventdev;
int event;
{
DX_CST *cstp;
int channum;
/*
* Retrieve USERCONTEXT for device
*/
sr_getparm(eventdev, SR_USERCONTEXT, &channum);
/*
* Switch according to the event received.
*/
switch ( event ) {
case TDX_SETHOOK:
cstp = (DX_CST *)sr_getevtdatap();
switch( cstp->cst_event) {
case DX_ONHOOK:
/* Go offhook next */
printf("Received onhook event\n");
if (dx_sethook(dxinfo[ channum ].chdev, DX_OFFHOOK, EV_ASYNC) == -1) {
printf("FAILED: dx_sethook(%s, DX_OFFHOOK): %s (error #%d)\n",
ATDV_NAMEP(dxinfo[channum].chdev),
ATDV_ERRMSGP(dxinfo[channum].chdev),
ATDV_LASTERR(dxinfo[channum].chdev));
return(1);
}
break;
case DX_OFFHOOK:
/* dial next */
printf("Received offhook event\n");
if (dx_dial(dxinfo[channum].chdev, "12025551212", NULL, EV_ASYNC) == -1) {
printf("FAILED: dx_dial(%s): %s (error #%d)\n",
ATDV_NAMEP(dxinfo[channum].chdev),
ATDV_ERRMSGP(dxinfo[channum].chdev),
ATDV_LASTERR(dxinfo[channum].chdev));
return(1);
}
break;
}
break;
case TDX_DIAL:
/* Next go onhook */
printf("Received TDX_DIAL event\n");
if (dx_sethook(dxinfo[ channum ].chdev, DX_ONHOOK, EV_ASYNC) == -1) {
printf("FAILED: dx_sethook(%s, DX_ONHOOK): %s (error #%d)\n",
ATDV_NAMEP(dxinfo[channum].chdev),
ATDV_ERRMSGP(dxinfo[channum].chdev),
ATDV_LASTERR(dxinfo[channum].chdev));
return(1);
}
}
return(0);
}
Click here to contact Dialogic Customer Engineering
Copyright 2001, Dialogic Corporation