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

📄 gc_basic_call_model.c

📁 dialogic 板卡globalcall 测试代码
💻 C
📖 第 1 页 / 共 5 页
字号:
		if ((port[index].log_fp = fopen(temp_filename, "w")) == NULL) {
			printf("\nCannot open log file %s for write\n", temp_filename);
			perror("Reason is: ");
			exitdemo(1);
		}
		printf("%s successfully opened\n", temp_filename); 
		
	} /* End of for loop */
	return 1;
}

/****************************************************************
*			NAME: inbound_application(struct channel *pline)
* DESCRIPTION: Place holder for your inbound application code in the connected state
*		  INPUT: pline - pointer to port data structure
*		RETURNS: NA
*	  CAUTIONS: none
****************************************************************/
static void inbound_application(struct channel *pline)
{
	/* Place holder - your app code goes here */
}
/****************************************************************
*			NAME: outbound_application(struct channel *pline)
* DESCRIPTION: Place holder for your outbound application code in the connected state
*		  INPUT: pline - pointer to port data structure
*		RETURNS: NA
*	  CAUTIONS: none
****************************************************************/
static void outbound_application(struct channel *pline)
{
	/*************************************************************************/
	/* YOUR APP WOULD PUT ITS WORK HERE													 */
	/* however for purposes of the demo, stay in the connected state			 */
	/* at least one second. This is because not all technologies and all		 */
	/* protocols support dropcall immediately after connected in the default */
	/* shipped configuration																 */
	/*************************************************************************/
	time(&pline->dropcall_time);
	pline->dropcall_time += 2;			/* stay connected at least one second */
												/* 2 is chosen because the granularity is 1 sec */
	printandlog(pline->index, MISC, NULL, "gc_DropCall() will be issued in 1-2 seconds");
}

/****************************************************************
*			NAME: drop_outbound_calls_if_required(void)
* DESCRIPTION: This drops outbound side calls if required
*					For purposes of the demo, a call stays in the connected
*					state state for a second or two, then is dropped by the outbound side
*					Your application does not need this code
*					and hence it is not optimized
*		RETURNS: NA
*	  CAUTIONS: none
****************************************************************/
static void drop_outbound_calls_if_required(void)
{
	int					index;
	struct channel		*pline;
	time_t				current_time;								/* in seconds */
	char					str[MAX_STRING_SIZE];

	time(&current_time);												/* get the current time in seconds */


	/* check all devices for an "expired" drop call time */
	/* assumes caller of gc_ResetLinedev() set dropcall_time = 0 */
	for (index = 0; index < num_devices; index++) {
		pline = &port[index];				
		if (pline->dropcall_time && (pline->dropcall_time <= current_time)) {			/* check if time tripped */
			pline->dropcall_time = 0;								/* drop call is no longer required */

			if (gc_DropCall(pline->crn, GC_NORMAL_CLEARING, EV_ASYNC) != GC_SUCCESS) {
				sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Failed", pline->crn);
				printandlog(pline->index, GC_APIERR, NULL, str);
				printandlog(pline->index, STATE, NULL, " ");
				exitdemo(1);
			}
			printandlog(index, MISC_WITH_NL, NULL, "********* Dropping outbound call from drop_outbound_calls_if_required() *********");
			sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Success", pline->crn);
			printandlog(pline->index, GC_APICALL, NULL, str);

			/* Set the dropcall flag to YES on the related channel */
			pline->dropcall_active = YES;
		}
	}
}

/****************************************************************
*			NAME: process_event(void)
* DESCRIPTION: Function to handle the GlobalCall Events 
*		RETURNS: NA
*	  CAUTIONS: none
****************************************************************/
void process_event(void)
{
	METAEVENT			metaevent;
	struct channel		*pline;
	char					str[MAX_STRING_SIZE];
	int					index;				/* Device index */
	int					evttype;
	GC_INFO				t_info;	  			/* Structure which stores information about GC related errors */ 
	
	/* Populate the metaEvent structure */
	if(gc_GetMetaEvent(&metaevent) != GC_SUCCESS)
	{
		printandlog(ALL_DEVICES, GC_APIERR, NULL, "gc_GetMetaEvent() failed");
		exitdemo(1);								/* serious problem - should never fail */
	}

	/* process GlobalCall events */
	if ((metaevent.flags & GCME_GC_EVENT) == 0)	{
		/*********************************************************************/
		/* Your application might have non-GC events , e.g. voice or fax		*/
		/* events that need to be processed. That would be done here.			*/
		/* However for the purposes of the demo, non_GC events are only		*/
		/* logged. Most likely you will need to do some sort of a				*/
		/* search of the port array to find the associated data structure		*/
		/* for this event. Since the event is not a GC event,						*/
		/* gc_GetUsrAttr() cannot help find the associated GC data structure */
		/*********************************************************************/
		sprintf(str, "Received a non-GC Event 0x%lx\n", metaevent.evttype);
		printandlog(ALL_DEVICES, MISC, NULL, str);
		return;												/* RETURN POINT */
	}
	/**************************************/
	/* when here => processing a GC event */
	/**************************************/
	/* initialize pline to port[index],
	The pointer to this structure was stored in GC
	during gc_OpenEx() */
	pline = (struct channel *) metaevent.usrattr;
	
	/* Retrieve device index */
	index = pline->index;

	evttype = metaevent.evttype;

	printandlog(index, MISC_WITH_NL, NULL, "********* Received a GC event *********");
	printandlog(index, EVENT, NULL, GCEV_MSG(evttype));
	printandlog(index, STATE, NULL, " is the current GC call state ");

	/* 1st handle the generic events */

	switch (evttype) 
	{
		case GCEV_FATALERROR:
			printandlog(index, GC_RESULT_INFO, &metaevent, "Reason for fatalerror ");
			printandlog(index, STATE, NULL, " ");

			if (gc_ResultInfo(&metaevent, &t_info) < 0) {
				sprintf(str, "gc_ResultInfo() call failed");
				printandlog(index, GC_APIERR, NULL, str);
				exitdemo(1);
			}

			if (t_info.gcValue == GCRV_RESETABLE_FATALERROR) {
				pline->dropcall_time = 0;								/* in case on */
				pline->resetlinedev_active = YES;					/* reset linedevice is on as a background process */
				/* do nothing else= wait till the GCEV_RESETLINEDEV completion event arrives */
			} else if (t_info.gcValue == GCRV_RECOVERABLE_FATALERROR) {
				/* do a close and open on recoverable, fatal errors */
				printandlog(index, MISC, NULL, " Recoverable fatal error occurred - closing device and re-opening it");
				if (gc_Close(port[index].ldev) < 0) {
					printandlog(index, GC_APIERR, NULL, "gc_Close() failed");
					exitdemo(1);
				}
				open_device(index);

			} else {
				printandlog(index, MISC, NULL, " Non-recoverable fatal error occurred");
				exitdemo(1);
			}
			break;				

		case GCEV_BLOCKED:
			pline->blocked = YES;						/* Nothing to do when a blocked event occurs */
			break;
			
		case GCEV_RESETLINEDEV:
			pline->call_state = GCST_NULL;			/* reset internal variables to that of beginning */
			pline->crn = 0;								/* except blocked/unblocked which are not affected by */
			pline->waitcall_active = NO;				/* GCEV_RESETLINEDEV */
			pline->dropcall_active = NO;
			pline->makecall_active = NO;
			pline->resetlinedev_active = NO;
			if (pline->blocked == NO) {				/* must further process the event if unblocked */
				if (pline->direction == DIR_IN) {
					process_inbound_event(pline, &metaevent);
				} else {
					process_outbound_event(pline, &metaevent);
				}
			}
			break;

		/* Note: for purposes of the demo, we will assume that gc_ResetLineDev() */
		/* does not fail or if it fails the 1st time, it will recover the 2nd time */
		case GCEV_TASKFAIL:
			printandlog(index, GC_RESULT_INFO, &metaevent, "Reason for taskfail ");
			printandlog(index, STATE, NULL, " ");

			/* best can do is a reset linedevice */
			pline->dropcall_time = 0;								/* in case on */
			if (gc_ResetLineDev(port[index].ldev, EV_ASYNC) != GC_SUCCESS) {
				sprintf(str, "gc_ResetLineDev(linedev=%ld, mode=EV_ASYNC) Failed", port[index].ldev);
				printandlog(index, GC_APIERR, NULL, str);
				exitdemo(1);
			}
			pline->resetlinedev_active = YES;
			sprintf(str, "gc_ResetLineDev(linedev=%ld, mode=EV_ASYNC) Success", port[index].ldev);
			printandlog(index, GC_APICALL, NULL, str);
			break;											/* nothing more can do until the completion event arrives */

		case GCEV_DISCONNECTED:
			if (pline->resetlinedev_active == NO) {
				process_disconnected_event(pline);	/* process the disconnected event */
			}
			break;

		case GCEV_UNBLOCKED:
			pline->blocked = NO;							/* blocked/unblocked do not cause state transitions */
			if (pline->resetlinedev_required_after_unblocked == YES) {
				pline->resetlinedev_required_after_unblocked = NO;

				if (gc_ResetLineDev(port[index].ldev, EV_ASYNC) != GC_SUCCESS) {
					sprintf(str, "gc_ResetLineDev(linedev=%ld, mode=EV_ASYNC) Failed", port[index].ldev);
					printandlog(index, GC_APIERR, NULL, str);
					exitdemo(1);
				}
				pline->resetlinedev_active = YES;
				sprintf(str, "gc_ResetLineDev(linedev=%ld, mode=EV_ASYNC) Success", port[index].ldev);
				printandlog(index, GC_APICALL, NULL, str);
				break;											/* nothing more can do until the completion event arrives */
			}


			/* fall through on purpose so the unblocked event will be handled */

		default:
			if (pline->resetlinedev_active == NO) {	/* ignore all call related events with reset linedevice active */
				if (pline->direction == DIR_IN) {
					process_inbound_event(pline, &metaevent);
				} else {
					process_outbound_event(pline, &metaevent);
				}
			}
			break;
	}
	printandlog(index, STATE, NULL, " is the new GC call state after processing the event");
}

/****************************************************************
*			NAME: process_disconnected_event(struct channel *pline)
* DESCRIPTION: Function to process a disconnected event
*		 INPUTS: pline - pointer to entry in port table
*		RETURNS: NA
*	  CAUTIONS: Assumes event logging already done
****************************************************************/
static void process_disconnected_event(struct channel *pline)
{
	char		str[MAX_STRING_SIZE];

	switch (pline->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"); 
				break;
			}
			/* 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 */

		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->dropcall_active == NO)
			{
				if (gc_DropCall(pline->crn, GC_NORMAL_CLEARING, EV_ASYNC) != GC_SUCCESS)
				{
					sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Failed", pline->crn);
					printandlog(pline->index, GC_APIERR, NULL, str);
					printandlog(pline->index, STATE, NULL, " ");
					exitdemo(1);
				}
				sprintf(str, "gc_DropCall(crn=0x%lx, cause=GC_NORMAL_CLEARING, mode=EV_ASYNC) Success", pline->crn);
				printandlog(pline->index, GC_APICALL, NULL, str);
				pline->dropcall_active = YES;
			}
			pline->call_state = GCST_DISCONNECTED;
			break;
	}
}

/****************************************************************
*			NAME: process_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_inbound_event(struct channel *pline, METAEVENT *metaeventp)
{
	int		evttype, index, call_state;
	char		str[MAX_STRING_SIZE];
	int		unexpected_event = 0;					/*assume not till proven otherwise */
																/* May be overridden for GCEV_UNBLOCKED */
	evttype = metaeventp->evttype;
	index = pline->index;
	call_state = pline->call_state;

	/* Implement the state machine */
	switch (pline->call_state)
	{
		/************************************/
		/* first come the call setup states */
		/************************************/
		case GCST_NULL:
		{
			switch (evttype)
			{
				case GCEV_UNBLOCKED:
					if (pline->waitcall_active == YES) {
						break;						/* waitcall already done - don't do again */
					}
					/* FALL THROUGH ON PURPOSE */
	
				case GCEV_RESETLINEDEV:
					/* Note: by definition, waitcall is not active at this point */
					if (pline->blocked == NO) {
						if (gc_WaitCall(pline->ldev, NULL, NULL, -1, EV_ASYNC) != GC_SUCCESS) {
							sprintf(str, "gc_WaitCall(linedev=%ld, crnp=NULL, waittime=0, mode=EV_ASYNC) Failed", pline->ldev);
							printandlog(index, GC_APIERR, NULL, str);
							exitdemo(1);
						}
						pline->waitcall_active = YES;
						sprintf(str, "gc_WaitCall(linedev=%ld, crnp=NULL, waittime=0, mode=EV_ASYNC) Success", pline->ldev);
						printandlog(index, GC_APICALL, NULL, str);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -