All pastes #261458 Raw Edit

Stuff

public text v1 · immutable
#261458 ·published 2006-11-29 07:25 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\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;

}