📄 gc_basic_call_model.c
字号:
}
}
}
pline->resetlinedev_required_after_unblocked = YES; /* try again later */
}
break;
case GCEV_DISCONNECTED:
if (pline->resetlinedev_active == NO) {
process_disconnected_event(pline, &metaevent); /* process the disconnected event */
}
break;
default:
if (pline->resetlinedev_active == NO) { /* ignore all call related events with reset linedevice active */
if (pline->direction == DIR_IN) {
process_call_related_inbound_event(pline, &metaevent);
} else {
process_call_related_outbound_event(pline, &metaevent);
}
}
break;
}
printandlog(index, STATE, NULL, " is the new GC call state after processing the event", callindex);
}
/****************************************************************
* NAME: void print_alarm_info(METAEVENTP metaeventp, struct channel *pline)
* DESCRIPTION: Prings alarm information
* INPUTS: metaeventp - pointer to the alarm event
* pline - pointer to the channel data structure
* RETURNS: NA
* CAUTIONS: Assumes already known to be an alarm event
****************************************************************/
static void print_alarm_info(METAEVENTP metaeventp, struct channel *pline)
{
long alarm_number;
char *alarm_name;
unsigned long alarm_source_objectID;
char *alarm_source_object_name;
char str[MAX_STRING_SIZE];
if (gc_AlarmNumber(metaeventp, &alarm_number) != GC_SUCCESS)
{
sprintf(str, "gc_AlarmNumber(...) FAILED");
printandlog(pline->index, GC_APIERR, NULL, str, 0);
printandlog(pline->index, STATE, NULL, " ", 0);
exitdemo(1);
}
if (gc_AlarmName(metaeventp, &alarm_name) != GC_SUCCESS)
{
sprintf(str, "gc_AlarmName(...) FAILED");
printandlog(pline->index, GC_APIERR, NULL, str, 0);
printandlog(pline->index, STATE, NULL, " ", 0);
exitdemo(1);
}
if (gc_AlarmSourceObjectID(metaeventp, &alarm_source_objectID) != GC_SUCCESS)
{
sprintf(str, "gc_AlarmSourceObjectID(...) FAILED");
printandlog(pline->index, GC_APIERR, NULL, str, 0);
printandlog(pline->index, STATE, NULL, " ", 0);
exitdemo(1);
}
if (gc_AlarmSourceObjectName(metaeventp, &alarm_source_object_name) != GC_SUCCESS)
{
sprintf(str, "gc_AlarmSourceObjectName(...) FAILED");
printandlog(pline->index, GC_APIERR, NULL, str, 0);
printandlog(pline->index, STATE, NULL, " ", 0);
exitdemo(1);
}
sprintf(str, "Alarm %s (0x%lx) occurred on ASO %s (%d)",
alarm_name, alarm_number, alarm_source_object_name, (int) alarm_source_objectID);
printandlog(pline->index, MISC, NULL, str, 0);
}
/****************************************************************
* NAME: process_disconnected_event(struct channel *pline, METAEVENT *metaeventp)
* DESCRIPTION: Function to process a disconnected event
* INPUTS: pline - pointer to entry in port table
* metaeventp - pointer to the current metaevent
* RETURNS: NA
* CAUTIONS: Assumes event logging already done
****************************************************************/
static void process_disconnected_event(struct channel *pline, METAEVENT *metaeventp)
{
char str[MAX_STRING_SIZE];
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;
}
switch (pline->call[callindex].call_state)
{
case GCST_IDLE:
/*************************************************************/
/* this represents a simultaneous disconnect */
/* do nothing as gc_DropCall() must have already been issued */
/* to reach this point! */
/*************************************************************/
break;
case GCST_NULL:
/* In case have a disconnect before dialing is reached */
if (pline->makecall_active == NO) {
/* this represents an error */
printandlog(pline->index, MISC, NULL, "Received GCEV_DISCONNECTED in NULL call state", 0);
/* however, there is a PT - 24402 - which indicates that the inbound side */
/* may under alarm conditions receive a disconnected event */
/* even though the call has not been offered */
/* the other work-around is to enable the detected state, but */
/* for purposes of showing a second work-around, we will "create" the call */
/* and then drop and release it */
pline->call[callindex].crn = metaeventp->crn; /* "create the call */
/* the call state will be init in default */
/* break; - when PT24402 is fixed, put this back in and pull the call "creation" */
}
/* fall through on purpose - need to do a dropcall and release call since there is a call active */
/* may have reached this condition if there is a problem before dialing */
/* or the inbound side has not enabled detection of events and the disconnected */
/* event arrives (usually due to alarm conditions) without the app previously */
/* being informed the call exists */
default:
/* GCEV_DISCONNECTED is allowed in all other call states */
/* If dropcall is already active, don't reissue it */
/* this represents a simultaneous disconnect */
if(pline->call[callindex].dropcall_active == NO)
{
if (gc_DropCall(pline->call[callindex].crn, GC_NORMAL_CLEARING, EV_ASYNC) != GC_SUCCESS)
{
sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Failed", pline->call[callindex].crn);
printandlog(pline->index, GC_APIERR, NULL, str, 0);
printandlog(pline->index, STATE, NULL, " ", callindex);
exitdemo(1);
}
sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Success", pline->call[callindex].crn);
printandlog(pline->index, GC_APICALL, NULL, str, 0);
pline->call[callindex].dropcall_active = YES;
}
pline->call[callindex].call_state = GCST_DISCONNECTED;
pline->dropcall_time = 0; /* dropcall is no longer required */
break;
}
}
/****************************************************************
* NAME: process_call_related_inbound_event(struct channel *pline, METAEVENT *metaeventp)
* DESCRIPTION: Function to process inbound 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_inbound_event(struct channel *pline, METAEVENT *metaeventp)
{
int evttype, index;
char str[MAX_STRING_SIZE];
int unexpected_event = 0; /*assume not till proven otherwise */
/* May be overridden for GCEV_UNBLOCKED */
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;
}
/* Implement the state machine */
switch (pline->call[callindex].call_state)
{
/************************************/
/* first come the call setup states */
/************************************/
case GCST_NULL:
{
switch (evttype)
{
case GCEV_OFFERED:
process_offered_event(metaeventp, pline);
break;
default:
unexpected_event = 1;
break;
}
break;
/* end of case GCST_NULL */
}
case GCST_OFFERED:
{
if (evttype == GCEV_ACCEPT) {
pline->call[callindex].call_state = GCST_ACCEPTED;
/* Microsoft Phoenix Version 5.0 Soft SIP phone requires SDP field in OK event so we */
/* specify coders prior to calling gc_AnswerCall( ) to ensure OK event has SDP field.*/
/* Though done specifically for Phoenix interopability, this will not affect */
/* interoperability with other SIP clients. */
if(pline->techtype == SIP) {
gc_set_channel_codecs(pline->index);
}
/* Note: if both answercall and acceptcall use 0 rings */
/* then the outbound side may not get an alerting event */
/* this behavior is technology/protocol dependent */
if (gc_AnswerCall(pline->call[callindex].crn, 0, EV_ASYNC) != GC_SUCCESS) {
sprintf(str, "gc_AnswerCall(crn=0x%lx, # of rings=0, mode=EV_ASYNC) Failed", pline->call[callindex].crn);
printandlog(index, GC_APIERR, NULL, str, 0);
exitdemo(1);
}
sprintf(str, "gc_AnswerCall(crn=0x%lx, mode=EV_ASYNC) Success", pline->call[callindex].crn);
printandlog(index, GC_APICALL, NULL, str, 0);
} else {
unexpected_event = 1;
}
break;
}
case GCST_ACCEPTED:
{
if (evttype == GCEV_ANSWERED) {
/* Do nothing but change the state to connected. The call will be cleared from
outbound side. Just wait for Disconnect */
/* Your application specific code will go here */
pline->call[callindex].call_state = GCST_CONNECTED;
/* Increment the total calls on this device */
pline->numb_calls++;
/* Increment the total inbound calls on all devices */
in_calls++;
inbound_application(pline); /* YOUR APPLICATION CODE IS CALLED HERE */
} else {
unexpected_event = 1;
}
break;
}
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() */
/*************************************************/
unexpected_event = 1; /* recall that GCEV_DISCONNECTED is handled elsewhere */
break;
}
/*************************************/
/* now come the call teardown states */
/*************************************/
case GCST_DISCONNECTED:
{
/* If the GCEV_OFFERED event is observed in this state,
then add the code that in located in GCST_IDLE state
to resolved the issue. */
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);
} else {
unexpected_event = 1;
}
break;
}
case GCST_IDLE:
{
/* In most cases, only GCEV_RELEASECALL will be seen in this state,
but GCEV_OFFERED can be received after gc_ReleaseCallEx() and
before GCEV_RELEASECALL. */
if (evttype == GCEV_RELEASECALL) {
pline->call[callindex].call_state = GCST_NULL;
pline->call[callindex].crn = 0;
} else if (evttype == GCEV_OFFERED) {
process_offered_event(metaeventp, pline);
} else {
unexpected_event = 1;
}
break;
}
default:
{
/* Should never get here */
printandlog(index, MISC, NULL, "Invalid state in process_call_related_inbound_event()", 0);
printandlog(index, STATE, NULL, " ", callindex);
break;
}
}
if (unexpected_event && (evttype != GCEV_UNBLOCKED)) {
printandlog(index, GC_RESULT_INFO, metaeventp, "Event was unexpected in the current state", 0);
printandlog(index, STATE, NULL, " ", callindex);
}
}
/****************************************************************
* NAME: process_offered_event(struct channel *pline)
* DESCRIPTION: Function to process an offered event while in the NULL state
* INPUTS: pline - pointer to entry in port table
* RETURNS: NA
* CAUTIONS: Assumes event logging already done
****************************************************************/
static void process_offered_event(METAEVENT *metaeventp, struct channel *pline)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -