Stuff
public text v1 · immutablestatic 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\n",
(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)) {
#if 1
/* see if the timeout has been violated */
int timeout_violation = ast_tvdiff_ms(ast_tvnow(), started);
if ( timeout_violation > ( timeout * 1000 )) {
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;
}