All pastes #36601 Raw Edit

Stuff

public text v1 · immutable
#36601 ·published 2006-01-12 16:59 UTC
rendered paste body


static struct ast_channel *app_dial(const char *type, int format, void *data,
									int timeout, int *outstate,
									const char *cid_num, const char *cid_name)
{
	int state = 0;
	int cause = 0;
	int to;
	struct ast_channel *chan;
	struct ast_frame *f = NULL;
	int res = 0, ready = 0;

	chan = ast_request(type, format, data, &cause);
	
	if (!chan) {
		switch (cause) {
		case AST_CAUSE_BUSY:
			state = AST_CONTROL_BUSY;
			break;
		case AST_CAUSE_CONGESTION:
			state = AST_CONTROL_CONGESTION;
			break;
		}
		
		if (outstate)
			*outstate = state;
			
		ast_verbose("Unable to call channel %s/%s reason: %s\nn",
				(char *) type, (char *) data, ast_cause2str(cause));
		
		return NULL;
	}

	
	if (ast_call(chan, data, timeout)) {
		ast_verbose("Unable to request channel %s/%s\n", type,
				(char *) data);
		switch (cause) {
		case AST_CAUSE_BUSY:
			state = AST_CONTROL_BUSY;
			break;
		case AST_CAUSE_CONGESTION:
			state = AST_CONTROL_CONGESTION;
			break;
		}
		if (outstate)
			*outstate = state;
		return NULL;
	}

	struct timeval started;
	
	started = ast_tvnow();
	to = timeout;
	
	ast_set_callerid(chan, cid_num, cid_name, cid_num);

	while (timeout && (chan->_state != AST_STATE_UP)) {


#ifdef NODEBUG
		/* see if the timeout has been violated */
		int timeout_violation = ast_tvdiff_ms(ast_tvnow(), started);
		if ( timeout_violation > timeout) {
			state = AST_CONTROL_UNHOLD;
			ast_log(LOG_NOTICE, "We exceeded our AT-timeout\n");
			break;				/*doh! timeout */
		}
#endif

		

		if (chan) {
			f = ast_read(chan);
			if (f == NULL) {
				state = AST_CONTROL_HANGUP;
				res = 0;
				break;
			}

			if (f->frametype == AST_FRAME_CONTROL
				|| f->frametype == AST_FRAME_DTMF
				|| f->frametype == AST_FRAME_TEXT) {

				if (f->subclass == AST_CONTROL_RINGING) {
					state = f->subclass;
					ast_verbose("%s is ringing\n", chan->name);
				}

				if (((f->subclass == AST_CONTROL_BUSY)
					 || (f->subclass == AST_CONTROL_CONGESTION))) {

					state = f->subclass;
					ast_frfree(f);
					f = NULL;
					break;
				} else if (f->subclass == AST_CONTROL_ANSWER) {
					/* This is what we are hoping for */
					state = f->subclass;
					ast_frfree(f);
					f = NULL;
					ready = 1;
					break;
				} else {
					ast_log(LOG_NOTICE,
							"Don't know what to do about control frame: %d\n",
							f->subclass);
				}
				/* else who cares */
			}
			if (f) {
				ast_frfree(f);
			}
		}
	}
	if (chan && ready) {
		if (chan->_state == AST_STATE_UP)
			state = AST_CONTROL_ANSWER;
		res = 0;
	} else if (chan) {
		res = -1;
		ast_hangup(chan);
		chan = NULL;
	} else {
		res = -1;
	}

	*outstate = state;


	return chan;

}