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; }
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; }