Ejemplo n.º 1
0
int comeback_goto(struct parked_user *pu, struct parking_lot *lot)
{
	struct ast_channel *chan = pu->chan;
	char *peername_flat = ast_strdupa(pu->parker_dial_string);

	/* Flatten the peername so that it can be used for performing the timeout PBX operations */
	flatten_dial_string(peername_flat);

	if (lot->cfg->comebacktoorigin) {
		if (ast_exists_extension(chan, PARK_DIAL_CONTEXT, peername_flat, 1, NULL)) {
			ast_async_goto(chan, PARK_DIAL_CONTEXT, peername_flat, 1);
			return 0;
		} else {
			ast_log(LOG_ERROR, "Can not start %s at %s,%s,1 because extension does not exist. Terminating call.\n",
				ast_channel_name(chan), PARK_DIAL_CONTEXT, peername_flat);
			return -1;
		}
	}

	if (ast_exists_extension(chan, lot->cfg->comebackcontext, peername_flat, 1, NULL)) {
		ast_async_goto(chan, lot->cfg->comebackcontext, peername_flat, 1);
		return 0;
	}

	if (ast_exists_extension(chan, lot->cfg->comebackcontext, "s", 1, NULL)) {
		ast_verb(2, "Could not start %s at %s,%s,1. Using 's@%s' instead.\n", ast_channel_name(chan),
			lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
		ast_async_goto(chan, lot->cfg->comebackcontext, "s", 1);
		return 0;
	}

	ast_verb(2, "Can not start %s at %s,%s,1 and exten 's@%s' does not exist. Using 's@default'\n",
		ast_channel_name(chan),
		lot->cfg->comebackcontext, peername_flat, lot->cfg->comebackcontext);
	ast_async_goto(chan, "default", "s", 1);

	return 0;
}
Ejemplo n.º 2
0
static struct ast_frame *i4l_read(struct ast_modem_pvt *p)
{
    unsigned char result[256];
    short *b;
    struct ast_frame *f=NULL;
    int res;
    int x;
    if (p->ministate == STATE_COMMAND) {
        /* Read the first two bytes, first, in case it's a control message */
        res = read(p->fd, result, 2);
        if (res < 2) {
            /* short read, means there was a hangup? */
            /* (or is this also possible without hangup?) */
            /* Anyway, reading from unitialized buffers is a bad idea anytime. */
            if (errno == EAGAIN)
                return i4l_handle_escape(p, 0);
            return NULL;
        }
        if (result[0] == CHAR_DLE) {
            return i4l_handle_escape(p, result[1]);

        } else {
            if ((result[0] == '\n') || (result[0] == '\r'))
                return i4l_handle_escape(p, 0);
            /* Read the rest of the line */
            fgets(result + 2, sizeof(result) - 2, p->f);
            ast_modem_trim(result);
            if (!strcasecmp(result, "VCON")) {
                /* If we're in immediate mode, reply now */
                /*				if (p->mode == MODEM_MODE_IMMEDIATE) */
                return i4l_handle_escape(p, 'X');
            } else if (!strcasecmp(result, "BUSY")) {
                /* Same as a busy signal */
                return i4l_handle_escape(p, 'b');
            } else if (!strncasecmp(result, "CALLER NUMBER: ", 15 )) {
                strncpy(p->cid_num, result + 15, sizeof(p->cid_num)-1);
                return i4l_handle_escape(p, 0);
            } else if (!strcasecmp(result, "RINGING")) {
                if (option_verbose > 2)
                    ast_verbose(VERBOSE_PREFIX_3 "%s is ringing...\n", p->dev);
                return i4l_handle_escape(p, 'I');
            } else if (!strncasecmp(result, "RUNG", 4)) {
                /* PM2002: the line was hung up before we picked it up, bye bye */
                if (option_verbose > 2)
                    ast_verbose(VERBOSE_PREFIX_3 "%s was hung up on before we answered\n", p->dev);
                return NULL;
            } else if (!strncasecmp(result, "RING", 4)) {
                if (result[4]=='/')
                    strncpy(p->dnid, result + 5, sizeof(p->dnid)-1);
                return i4l_handle_escape(p, 'R');
            } else if (!strcasecmp(result, "NO CARRIER")) {
                if (option_verbose > 2)
                    ast_verbose(VERBOSE_PREFIX_3 "%s hung up on\n", p->dev);
                return NULL;
            } else if (!strcasecmp(result, "NO DIALTONE")) {
                /* There's no dialtone, so the line isn't working */
                ast_log(LOG_WARNING, "Device '%s' lacking dialtone\n", p->dev);
                return NULL;
            }
            if (option_debug)
                ast_log(LOG_DEBUG, "Modem said '%s'\n", result);
            return i4l_handle_escape(p, 0);
        }
    } else {
        /* We have to be more efficient in voice mode */
        b = (short *)(p->obuf + p->obuflen);
        while (p->obuflen/2 < 240) {
            /* Read ahead the full amount */
            res = read(p->fd, result, 240 - p->obuflen/2);
            if (res < 1) {
                /* If there's nothing there, just continue on */
                if (errno == EAGAIN)
                    return i4l_handle_escape(p, 0);
                ast_log(LOG_WARNING, "Read failed: %s\n", strerror(errno));
                return NULL;
            }

            for (x=0; x<res; x++) {
                /* Process all the bytes that we've read */
                switch(result[x]) {
                case CHAR_DLE:
#if 0
                    ast_log(LOG_DEBUG, "Ooh, an escape at %d...\n", x);
#endif
                    if (!p->escape) {
                        /* Note that next value is
                           an escape, and continue. */
                        p->escape++;
                        break;
                    } else {
                        /* Send as is -- fallthrough */
                        p->escape = 0;
                    }
                default:
                    if (p->escape) {
                        ast_log(LOG_DEBUG, "Value of escape is %c (%d)...\n", result[x] < 32 ? '^' : result[x], result[x]);
                        p->escape = 0;
                        if (f)
                            ast_log(LOG_WARNING, "Warning: Dropped a signal frame\n");
                        f = i4l_handle_escape(p, result[x]);
                        /* If i4l_handle_escape says NULL, say it now, doesn't matter
                        what else is there, the connection is dead. */
                        if (!f)
                            return NULL;
                    } else {
                        *(b++) = AST_MULAW((int)result[x]);
                        p->obuflen += 2;
                    }
                }
            }
            if (f)
                break;
        }
        if (f) {
            if( ! (!(p->dtmfmode & MODEM_DTMF_I4L) && f->frametype == AST_FRAME_DTMF))
                return f;
        }

        /* If we get here, we have a complete voice frame */
        p->fr.frametype = AST_FRAME_VOICE;
        p->fr.subclass = AST_FORMAT_SLINEAR;
        p->fr.samples = 240;
        p->fr.data = p->obuf;
        p->fr.datalen = p->obuflen;
        p->fr.mallocd = 0;
        p->fr.delivery.tv_sec = 0;
        p->fr.delivery.tv_usec = 0;
        p->fr.offset = AST_FRIENDLY_OFFSET;
        p->fr.src = __FUNCTION__;
        p->obuflen = 0;

        /* process with dsp */
        if (p->dsp) {
            f = ast_dsp_process(p->owner, p->dsp, &p->fr);
            if (f && (f->frametype == AST_FRAME_DTMF)) {
                ast_log(LOG_DEBUG, "Detected inband DTMF digit: %c on %s\n", f->subclass, p->dev);
                if (f->subclass == 'f') {
                    /* Fax tone -- Handle and return NULL */
                    struct ast_channel *ast = p->owner;
                    if (!p->faxhandled) {
                        p->faxhandled++;
                        if (strcmp(ast->exten, "fax")) {
                            const char *target_context = ast_strlen_zero(ast->macrocontext) ? ast->context : ast->macrocontext;

                            if (ast_exists_extension(ast, target_context, "fax", 1, ast->cid.cid_num)) {
                                if (option_verbose > 2)
                                    ast_verbose(VERBOSE_PREFIX_3 "Redirecting %s to fax extension\n", ast->name);
                                /* Save the DID/DNIS when we transfer the fax call to a "fax" extension */
                                pbx_builtin_setvar_helper(ast, "FAXEXTEN", ast->exten);
                                if (ast_async_goto(ast, target_context, "fax", 1))
                                    ast_log(LOG_WARNING, "Failed to async goto '%s' into fax of '%s'\n", ast->name, target_context);
                            } else
                                ast_log(LOG_NOTICE, "Fax detected, but no fax extension\n");
                        } else
                            ast_log(LOG_DEBUG, "Already in a fax extension, not redirecting\n");
                    } else
                        ast_log(LOG_DEBUG, "Fax already handled\n");
                    p->fr.frametype = AST_FRAME_NULL;
                    p->fr.subclass = 0;
                    f = &p->fr;
                }
                return f;
            }
        }

        return &p->fr;
    }
    return NULL;
}