📄 gc_basic_call_model.c
字号:
{
char dnis[GC_ADDRSIZE];
char ani[GC_ADDRSIZE];
char caller_name[GC_ADDRSIZE];
char str[MAX_STRING_SIZE];
int callindex;
/* Retrieve CRN */
callindex = existCRN(metaeventp->crn, pline);
if (callindex == OUT_OF_RANGE) {
printandlog(pline->index, MISC, NULL, "metaeventp->crn unexpectedly not found for a GCEV_OFFERED event", 0);
exitdemo(1);
}
/* Save the CRN in port[index] and call Acceptcall */
pline->call[callindex].call_state = GCST_OFFERED;
pline->call[callindex].crn = metaeventp->crn;
/* show some technology specific functionality */
/* get destination and origination if not ANALOG */
if (pline->techtype != ANALOG) {
/* first, get called party number */
if (gc_GetCallInfo(pline->call[callindex].crn, DESTINATION_ADDRESS, dnis) == GC_SUCCESS) {
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Success - called party = %s", pline->call[callindex].crn, dnis);
} else {
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Failure - called party not available ", pline->call[callindex].crn);
}
printandlog(pline->index, GC_APICALL, NULL, str, 0);
/* do application specific dnis event processing here */
/* For simplicity's sake, max DDI logic is not shown here */
/* next get the calling party here */
if (gc_GetCallInfo(pline->call[callindex].crn, ORIGINATION_ADDRESS, ani) == GC_SUCCESS) {
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Success - calling party = %s", pline->call[callindex].crn, ani);
} else {
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Failure - calling party not available", pline->call[callindex].crn);
}
printandlog(pline->index, GC_APICALL, NULL, str, 0);
} else {
/* get calling party, if Analog */
if (gc_GetCallInfo(pline->call[callindex].crn, ORIGINATION_ADDRESS, ani) == GC_SUCCESS) {
/* get ANI */
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Success - calling party = %s", pline->call[callindex].crn, ani);
} else {
sprintf(str, "gc_GetCallInfo(crn=0x%lx) Failure - calling party not available", pline->call[callindex].crn);
}
printandlog(pline->index, GC_APICALL, NULL, str, 0);
/* get the call info */
if (gc_GetCallInfo(pline->call[callindex].crn, CALLNAME, caller_name) == GC_SUCCESS) {
sprintf(str, "gc_GetCallInfo(crn=0x%lx, CALLNAME) Success, name = %s",
pline->call[callindex].crn, caller_name);
} else {
sprintf(str, "gc_GetCallInfo(crn=0x%lx, CALLNAME) Failure, name not available",
pline->call[callindex].crn);
}
printandlog(pline->index, GC_APICALL, NULL, str, 0);
}
/* Note: if # of rings is == 0 then the outbound side */
/* may not get the alerting event, depending upon the protocol */
/* if the number of rings is 1, there is an occasional problem in */
/* in the outbound side's ability to recognize the tone */
if (gc_AcceptCall(pline->call[callindex].crn, 3, EV_ASYNC) != GC_SUCCESS) {
sprintf(str, "gc_AcceptCall(crn=0x%lx, # of rings=3, mode=EV_ASYNC) Failed", pline->call[callindex].crn);
printandlog(pline->index, GC_APIERR, NULL, str, 0);
exitdemo(1);
}
sprintf(str, "gc_AcceptCall(crn=0x%lx, mode=EV_ASYNC) Success", pline->call[callindex].crn);
printandlog(pline->index, GC_APICALL, NULL, str, 0);
if ( dx_clrdigbuf( pline->chdev ) == -1 ) {
}
}
/****************************************************************
* NAME: process_call_related_outbound_event(struct channel *pline, METAEVENT *metaeventp)
* DESCRIPTION: Function to process outbound GlobalCall event
* INPUTS: pline - pointer to entry in port table
* metaeventp - pointer to the metaevent structure
* RETURNS: NA
* CAUTIONS: Tightly coupled with process_event() for pre-processing
* Assumes event logging already done
* Disconnected event already handled
****************************************************************/
static void process_call_related_outbound_event(struct channel *pline, METAEVENT *metaeventp)
{
int evttype, index;
int unexpected_event = 0; /* till proven otherwise */
char str[MAX_STRING_SIZE];
int callindex;
evttype = metaeventp->evttype;
index = pline->index;
/* Retrieve CRN */
callindex = existCRN(metaeventp->crn, pline);
if (callindex == OUT_OF_RANGE) {
/* CRN not found, so log error and return from function. */
sprintf(str, "CRN not found");
printandlog(pline->index, MISC_WITH_NL, NULL, str, 0);
return;
}
switch (pline->call[callindex].call_state)
{
/************************************/
/* first come the call setup states */
/************************************/
case GCST_NULL:
{
switch (evttype)
{
case GCEV_ALERTING: /* just change the state to alerting - no other action is necessary */
pline->call[callindex].call_state = GCST_ALERTING;
break;
case GCEV_PROCEEDING: /* just change the state to proceeding - no other action is necessary */
pline->call[callindex].call_state = GCST_PROCEEDING;
break;
/* This case can happen in some technologies/protocols if the inbound side */
/* answered the call without ringing (i.e. if acceptcall was issued, */
/* then the rings parameter in both acceptcall and anwercall was 0 */
/* if only answercall was issued, then the # of rings was 0 */
/* The internal GC call state should be Dialing, but the dialing event */
/* is disabled by default and we did not enable it */
case GCEV_CONNECTED:
process_connected_event(pline, metaeventp);
break;
default:
unexpected_event = 1;
break;
}
break;
}
case GCST_ALERTING:
{
if (evttype == GCEV_CONNECTED) {
process_connected_event(pline, metaeventp);
} else {
unexpected_event = 1;
}
break;
}
case GCST_PROCEEDING:
{
switch (evttype)
{
case GCEV_ALERTING: /* just change the state to alerting - no other action is necessary */
pline->call[callindex].call_state = GCST_ALERTING;
break;
case GCEV_CONNECTED:
process_connected_event(pline, metaeventp);
break;
default:
unexpected_event = 1;
break;
}
break;
}
/*************************************/
/* now come the call teardown states */
/*************************************/
case GCST_CONNECTED:
{
/*************************************************/
/* Depending upon your application, you may or */
/* may not have application specific event */
/* handling here for when in the connected state */
/* You could also have your app specific code */
/* in process_event() */
/*************************************************/
if (evttype != GCEV_DROPCALL) { /* recall the outbound side issues a gc_DropCall() */
unexpected_event = 1; /* for the purposes of this demo */
break;
}
/* FALL THROUGH ON PURPOSE since this is one of the 2 ways of reaching Idle */
/* the other being a disconnected event */
}
case GCST_DISCONNECTED:
{
if (evttype == GCEV_DROPCALL) {
pline->call[callindex].dropcall_active = NO;
/* Call ReleaseCall */
pline->call[callindex].call_state = GCST_IDLE;
if (gc_ReleaseCallEx(pline->call[callindex].crn, EV_ASYNC) != GC_SUCCESS) {
sprintf(str, "gc_ReleaseCallEx(crn=0x%lx, EV_ASYNC) Failed", pline->call[callindex].crn);
printandlog(index, GC_APIERR, NULL, str, 0);
exitdemo(1);
}
sprintf(str, "gc_ReleaseCallEx(crn=0x%lx, EV_ASYNC) Success", pline->call[callindex].crn);
printandlog(index, GC_APICALL, NULL, str, 0);
fflush(stdout);
break;
} else {
unexpected_event = 1;
}
break;
}
case GCST_IDLE:
{
if (evttype == GCEV_RELEASECALL) {
pline->call[callindex].call_state = GCST_NULL;
pline->call[callindex].crn = 0;
pline->makecall_active = NO; /* makecall is no longer active */
if(pline->intercall_delay) /* Set Inter-call Delay if specified */
{
time(&pline->intercall_time);
pline->intercall_time += pline->intercall_delay;
}
gc_demo_makecall(index);
} else {
unexpected_event = 1;
}
break;
}
default:
{
/* Should never get here */
printandlog(index, MISC, NULL, "Invalid state in process_call_related_outbound_event()", 0);
break;
}
}
if (unexpected_event && (evttype != GCEV_UNBLOCKED)) {
printandlog(index, GC_RESULT_INFO, metaeventp, "Event was unexpected in the current state", 0);
printandlog(index, EVENT, NULL, GCEV_MSG(evttype), 0);
printandlog(index, STATE, NULL, " ", callindex);
}
}
/****************************************************************
* NAME: process_connected_event(struct channel *pline, METAEVENT *metaeventp)
* DESCRIPTION: Function to process a connected event
* INPUTS: pline - pointer to entry in port table
* RETURNS: NA
* CAUTIONS: Assumes event logging already done
* Recall that this is only done for the outbound side
* as the GCEV_CONNECTED event is an outbound side event only
****************************************************************/
static void process_connected_event(struct channel *pline, METAEVENT *metaeventp)
{
char str[MAX_STRING_SIZE];
char value; /* for connect type */
int rc;
int callindex;
/* Retrieve CRN */
callindex = existCRN(metaeventp->crn, pline);
if (callindex == OUT_OF_RANGE) {
/* CRN not found, so log error and return from function. */
sprintf(str, "CRN not found");
printandlog(pline->index, MISC_WITH_NL, NULL, str, 0);
return;
}
/* Obtain connect type reason if not H323 nor SIP */
if ((pline->techtype != H323) &&
(pline->techtype != SIP) &&
(pline->techtype != SS7)){
/* print connect type */
rc = gc_GetCallInfo(pline->call[callindex].crn, CONNECT_TYPE, &value);
if (rc != GC_SUCCESS) {
if (rc == EGC_UNSUPPORTED) {
strcpy(str, "call connected - gc_GetCallInfo(CONNECT_TYPE) not supported");
} else {
strcpy(str, "call connected - gc_GetCallInfo(CONNECT_TYPE) error\n");
sprintf(str, "gc_GetCallInfo(crn=0x%lx, CONNECT_TYPE, &value) failed", pline->call[callindex].crn);
printandlog(pline->index, GC_APIERR, NULL, str, 0);
}
} else {
switch (value)
{
case GCCT_CAD :
strcpy(str, "call connected - cadence break");
break;
case GCCT_LPC :
strcpy(str, "call connected - loop current drop");
break;
case GCCT_PVD :
strcpy(str, "call connected - voice detection");
break;
case GCCT_PAMD :
strcpy(str, "call connected - answering machine");
break;
case GCCT_FAX :
strcpy(str, "call connected - FAX machine");
break;
case GCCT_NA :
strcpy(str, "call connected - call progress not applicable");
break;
default :
strcpy(str, "call connected - unknown connect type");
break;
}
}
printandlog(pline->index, MISC, NULL, str, 0);
}
pline->call[callindex].call_state = GCST_CONNECTED;
pline->numb_calls++; /* Increment the total calls on this device */
out_calls++; /* Increment the total outbound calls on all devices */
outbound_application(pline); /* call your application specific code here */
}
/****************************************************************
* NAME: enable_alarm_notification(struct channel *pline)
* DESCRIPTION: Enables all alarms notification for pline
* Also fills in pline->mediah
* INPUT: pline - pointer to channel data structure
* RETURNS: None - exits if error
* CAUTIONS: Does not sanity checking as to whether or not the technology supports
* alarms - assumes caller has done that already
****************************************************************/
static void enable_alarm_notification(struct channel *pline)
{
char str[MAX_STRING_SIZE];
int alarm_ldev; /* linedevice that alarms come on */
alarm_ldev = pline->ldev; /* until proven otherwise */
if (pline->techtype
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -