⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gc_basic_call_model.c

📁 dialogic gcwithvoice
💻 C
📖 第 1 页 / 共 5 页
字号:
						}
					}
				}
				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 + -