diff --git a/apps/app_queue.c b/apps/app_queue.c index b9afc6ac2a..2fea907e9c 100755 --- a/apps/app_queue.c +++ b/apps/app_queue.c @@ -338,7 +338,7 @@ static void *changethread(void *data) *loc = '\0'; loc++; } else { - ast_log(LOG_WARNING, "Can't change device with no technology!\n"); + ast_log(LOG_WARNING, "Can't change device '%s' with no technology!\n", sc->dev); free(sc); return NULL; } diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index bfb566d4e8..0dcd9d9d89 100755 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -721,6 +721,8 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state) tmp->type = type; tmp->fds[0] = readdev; tmp->nativeformats = AST_FORMAT_SLINEAR; + tmp->readformat = AST_FORMAT_SLINEAR; + tmp->writeformat = AST_FORMAT_SLINEAR; tmp->pvt->pvt = p; tmp->pvt->send_digit = alsa_digit; tmp->pvt->send_text = alsa_text; diff --git a/channels/chan_features.c b/channels/chan_features.c index dae202cf43..be1a88fa8d 100755 --- a/channels/chan_features.c +++ b/channels/chan_features.c @@ -60,6 +60,8 @@ struct feature_sub { struct ast_channel *owner; int inthreeway; int pfd; + int timingfdbackup; + int alertpipebackup[2]; }; static struct feature_pvt { @@ -80,6 +82,8 @@ static inline void init_sub(struct feature_sub *sub) { sub->inthreeway = 0; sub->pfd = -1; + sub->timingfdbackup = -1; + sub->alertpipebackup[0] = sub->alertpipebackup[1] = -1; } static inline int indexof(struct feature_pvt *p, struct ast_channel *owner, int nullok) @@ -115,9 +119,46 @@ static void wakeup_sub(struct feature_pvt *p, int a) } } -static void swap_subs(struct feature_pvt *p, int a, int b) +static void restore_channel(struct feature_pvt *p, int index) +{ + /* Restore timing/alertpipe */ + p->subs[index].owner->timingfd = p->subs[index].timingfdbackup; + p->subs[index].owner->pvt->alertpipe[0] = p->subs[index].alertpipebackup[0]; + p->subs[index].owner->pvt->alertpipe[1] = p->subs[index].alertpipebackup[1]; + p->subs[index].owner->fds[AST_MAX_FDS-1] = p->subs[index].alertpipebackup[0]; + p->subs[index].owner->fds[AST_MAX_FDS-2] = p->subs[index].timingfdbackup; +} + +static void update_features(struct feature_pvt *p, int index) { int x; + if (p->subs[index].owner) { + for (x=0;xsubs[index].owner->fds[x] = -1; + else + p->subs[index].owner->fds[x] = p->subchan->fds[x]; + } + if (!index) { + /* Copy timings from master channel */ + p->subs[index].owner->timingfd = p->subchan->timingfd; + p->subs[index].owner->pvt->alertpipe[0] = p->subchan->pvt->alertpipe[0]; + p->subs[index].owner->pvt->alertpipe[1] = p->subchan->pvt->alertpipe[1]; + if (p->subs[index].owner->nativeformats != p->subchan->readformat) { + p->subs[index].owner->nativeformats = p->subchan->readformat; + if (p->subs[index].owner->readformat) + ast_set_read_format(p->subs[index].owner, p->subs[index].owner->readformat); + if (p->subs[index].owner->writeformat) + ast_set_write_format(p->subs[index].owner, p->subs[index].owner->writeformat); + } + } else{ + restore_channel(p, index); + } + } +} + +static void swap_subs(struct feature_pvt *p, int a, int b) +{ int tinthreeway; struct ast_channel *towner; @@ -131,22 +172,8 @@ static void swap_subs(struct feature_pvt *p, int a, int b) p->subs[b].owner = towner; p->subs[b].inthreeway = tinthreeway; - - if (p->subs[a].owner) { - for (x=0;xsubs[a].owner->fds[x] = -1; - else - p->subs[a].owner->fds[x] = p->subchan->fds[x]; - } - } - if (p->subs[b].owner) { - for (x=0;xsubs[b].owner->fds[x] = -1; - else - p->subs[b].owner->fds[x] = p->subchan->fds[x]; - } + update_features(p,a); + update_features(p,b); wakeup_sub(p, a); wakeup_sub(p, b); } @@ -174,8 +201,10 @@ static struct ast_frame *features_read(struct ast_channel *ast) f = &null_frame; ast_mutex_lock(&p->lock); x = indexof(p, ast, 0); - if (!x && p->subchan) + if (!x && p->subchan) { + update_features(p, x); f = ast_read(p->subchan); + } ast_mutex_unlock(&p->lock); return f; } @@ -241,36 +270,42 @@ static int features_call(struct ast_channel *ast, char *dest, int timeout) struct feature_pvt *p = ast->pvt->pvt; int res = -1; int x; + char *dest2; - ast_mutex_lock(&p->lock); - x = indexof(p, ast, 0); - if (!x && p->subchan) { - if (p->owner->cid.cid_num) - p->subchan->cid.cid_num = strdup(p->owner->cid.cid_num); - else - p->subchan->cid.cid_num = NULL; - - if (p->owner->cid.cid_name) - p->subchan->cid.cid_name = strdup(p->owner->cid.cid_name); - else - p->subchan->cid.cid_name = NULL; - - if (p->owner->cid.cid_rdnis) - p->subchan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis); - else - p->subchan->cid.cid_rdnis = NULL; - - if (p->owner->cid.cid_ani) - p->subchan->cid.cid_ani = strdup(p->owner->cid.cid_ani); - else - p->subchan->cid.cid_ani = NULL; - - strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1); - strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1); - p->subchan->cdrflags = p->owner->cdrflags; - } else - ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n"); - ast_mutex_unlock(&p->lock); + dest2 = strchr(dest, '/'); + if (dest2) { + ast_mutex_lock(&p->lock); + x = indexof(p, ast, 0); + if (!x && p->subchan) { + if (p->owner->cid.cid_num) + p->subchan->cid.cid_num = strdup(p->owner->cid.cid_num); + else + p->subchan->cid.cid_num = NULL; + + if (p->owner->cid.cid_name) + p->subchan->cid.cid_name = strdup(p->owner->cid.cid_name); + else + p->subchan->cid.cid_name = NULL; + + if (p->owner->cid.cid_rdnis) + p->subchan->cid.cid_rdnis = strdup(p->owner->cid.cid_rdnis); + else + p->subchan->cid.cid_rdnis = NULL; + + if (p->owner->cid.cid_ani) + p->subchan->cid.cid_ani = strdup(p->owner->cid.cid_ani); + else + p->subchan->cid.cid_ani = NULL; + + strncpy(p->subchan->language, p->owner->language, sizeof(p->subchan->language) - 1); + strncpy(p->subchan->accountcode, p->owner->accountcode, sizeof(p->subchan->accountcode) - 1); + p->subchan->cdrflags = p->owner->cdrflags; + res = ast_call(p->subchan, dest2, timeout); + update_features(p, x); + } else + ast_log(LOG_NOTICE, "Uhm yah, not quite there with the call waiting...\n"); + ast_mutex_unlock(&p->lock); + } return res; } @@ -283,6 +318,7 @@ static int features_hangup(struct ast_channel *ast) ast_mutex_lock(&p->lock); x = indexof(p, ast, 0); if (x > -1) { + restore_channel(p, x); p->subs[x].owner = NULL; /* XXX Re-arrange, unconference, etc XXX */ } @@ -385,17 +421,19 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in ast_log(LOG_WARNING, "Called to put index %d already there!\n", index); return NULL; } - tmp = ast_channel_alloc(1); + tmp = ast_channel_alloc(0); if (!tmp) return NULL; if (tmp) { for (x=1;x<4;x++) { snprintf(tmp->name, sizeof(tmp->name), "Feature/%s/%s-%d", p->tech, p->dest, x); for (y=0;y<3;y++) { + if (y == index) + continue; if (p->subs[x].owner && !strcasecmp(p->subs[x].owner->name, tmp->name)) break; } - if (y < 3) + if (y >= 3) break; } tmp->type = type; @@ -404,6 +442,7 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in tmp->pvt->rawwriteformat = p->subchan->pvt->rawwriteformat; tmp->readformat = p->subchan->readformat; tmp->pvt->rawreadformat = p->subchan->pvt->rawreadformat; + tmp->nativeformats = p->subchan->readformat; tmp->pvt->pvt = p; tmp->pvt->send_digit = features_digit; tmp->pvt->call = features_call; @@ -434,6 +473,8 @@ static struct ast_channel *features_request(const char *type, int format, void * p = features_alloc(data, format); if (p && !p->subs[SUB_REAL].owner) chan = features_new(p, AST_STATE_DOWN, SUB_REAL); + if (chan) + update_features(p,SUB_REAL); return chan; } diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 4fc613c696..46cfadba34 100755 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -713,6 +713,8 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state) tmp->type = type; tmp->fds[0] = sounddev; tmp->nativeformats = AST_FORMAT_SLINEAR; + tmp->readformat = AST_FORMAT_SLINEAR; + tmp->writeformat = AST_FORMAT_SLINEAR; tmp->pvt->pvt = p; tmp->pvt->send_digit = oss_digit; tmp->pvt->send_text = oss_text; diff --git a/cli.c b/cli.c index 8a99c6e4b5..5571c6449e 100755 --- a/cli.c +++ b/cli.c @@ -633,6 +633,7 @@ static int handle_showchan(int fd, int argc, char *argv[]) struct ast_channel *c=NULL; struct timeval now; char buf[1024]; + char cdrtime[256]; long elapsed_seconds=0; int hour=0, min=0, sec=0; if (argc != 3) @@ -646,7 +647,9 @@ static int handle_showchan(int fd, int argc, char *argv[]) hour = elapsed_seconds / 3600; min = (elapsed_seconds % 3600) / 60; sec = elapsed_seconds % 60; - } + snprintf(cdrtime, sizeof(cdrtime), "%dh%dm%ds", hour, min, sec); + } else + strncpy(cdrtime, "N/A", sizeof(cdrtime) -1); ast_cli(fd, " -- General --\n" " Name: %s\n" @@ -664,7 +667,7 @@ static int handle_showchan(int fd, int argc, char *argv[]) " Frames in: %d%s\n" " Frames out: %d%s\n" " Time to Hangup: %ld\n" - " Elapsed Time: %dh%dm%ds\n" + " Elapsed Time: %s\n" " -- PBX --\n" " Context: %s\n" " Extension: %s\n" @@ -680,7 +683,7 @@ static int handle_showchan(int fd, int argc, char *argv[]) (c->cid.cid_dnid ? c->cid.cid_dnid : "(N/A)" ), ast_state2str(c->_state), c->_state, c->rings, c->nativeformats, c->writeformat, c->readformat, c->fds[0], c->fin & 0x7fffffff, (c->fin & 0x80000000) ? " (DEBUGGED)" : "", c->fout & 0x7fffffff, (c->fout & 0x80000000) ? " (DEBUGGED)" : "", (long)c->whentohangup, - hour, min, sec, + cdrtime, c->context, c->exten, c->priority, c->callgroup, c->pickupgroup, ( c->appl ? c->appl : "(N/A)" ), ( c-> data ? (!ast_strlen_zero(c->data) ? c->data : "(Empty)") : "(None)"), (ast_test_flag(c, AST_FLAG_BLOCKING) ? c->blockproc : "(Not Blocking)"));