diff options
-rw-r--r-- | apps/app_cdr.c | 3 | ||||
-rw-r--r-- | apps/app_voicemail.c | 12 | ||||
-rw-r--r-- | channels/chan_agent.c | 4 | ||||
-rw-r--r-- | channels/chan_alsa.c | 2 | ||||
-rw-r--r-- | channels/chan_features.c | 2 | ||||
-rw-r--r-- | channels/chan_gtalk.c | 2 | ||||
-rw-r--r-- | channels/chan_h323.c | 2 | ||||
-rw-r--r-- | channels/chan_iax2.c | 6 | ||||
-rw-r--r-- | channels/chan_local.c | 4 | ||||
-rw-r--r-- | channels/chan_mgcp.c | 2 | ||||
-rw-r--r-- | channels/chan_misdn.c | 2 | ||||
-rw-r--r-- | channels/chan_nbs.c | 2 | ||||
-rw-r--r-- | channels/chan_oss.c | 6 | ||||
-rw-r--r-- | channels/chan_phone.c | 2 | ||||
-rw-r--r-- | channels/chan_sip.c | 9 | ||||
-rw-r--r-- | channels/chan_skinny.c | 2 | ||||
-rw-r--r-- | channels/chan_vpb.cc | 2 | ||||
-rw-r--r-- | channels/chan_zap.c | 2 | ||||
-rw-r--r-- | include/asterisk/channel.h | 2 | ||||
-rw-r--r-- | main/cdr.c | 84 | ||||
-rw-r--r-- | main/channel.c | 32 | ||||
-rw-r--r-- | main/pbx.c | 6 | ||||
-rw-r--r-- | res/res_features.c | 149 |
23 files changed, 171 insertions, 168 deletions
diff --git a/apps/app_cdr.c b/apps/app_cdr.c index 60e48d7a2..c0d88fbbb 100644 --- a/apps/app_cdr.c +++ b/apps/app_cdr.c @@ -51,8 +51,7 @@ static int nocdr_exec(struct ast_channel *chan, void *data) u = ast_module_user_add(chan); if (chan->cdr) { - ast_cdr_free(chan->cdr); - chan->cdr = NULL; + ast_set_flag(chan->cdr, AST_CDR_FLAG_POST_DISABLED); } ast_module_user_remove(u); diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index b603f36e3..668915e1c 100644 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -1914,7 +1914,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in if (!ast_strlen_zero(fromstring)) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(fromstring)*3 + 200; if ((passdata = alloca(vmlen))) { @@ -1936,7 +1936,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in fprintf(p, "To: %s <%s>" ENDL, quote(vmu->fullname, passdata2, len_passdata), vmu->email); if (!ast_strlen_zero(emailsubject)) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(emailsubject) * 3 + 200; if ((passdata = alloca(vmlen))) { @@ -1990,7 +1990,7 @@ static void make_email_file(FILE *p, char *srcemail, struct ast_vm_user *vmu, in fprintf(p, "Content-Type: text/plain; charset=%s" ENDL "Content-Transfer-Encoding: 8bit" ENDL ENDL, charset); if (emailbody) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(emailbody)*3 + 200; if ((passdata = alloca(vmlen))) { @@ -2109,7 +2109,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char if (*pagerfromstring) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(fromstring)*3 + 200; if ((passdata = alloca(vmlen))) { @@ -2127,7 +2127,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char fprintf(p, "To: %s\n", pager); if (pagersubject) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(pagersubject) * 3 + 200; if ((passdata = alloca(vmlen))) { @@ -2146,7 +2146,7 @@ static int sendpage(char *srcemail, char *pager, int msgnum, char *context, char strftime(date, sizeof(date), "%A, %B %d, %Y at %r", &tm); if (pagerbody) { struct ast_channel *ast; - if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0))) { + if ((ast = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0))) { char *passdata; int vmlen = strlen(pagerbody)*3 + 200; if ((passdata = alloca(vmlen))) { diff --git a/channels/chan_agent.c b/channels/chan_agent.c index 26f8ca546..50b3666d9 100644 --- a/channels/chan_agent.c +++ b/channels/chan_agent.c @@ -918,9 +918,9 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state) } #endif if (p->pending) - tmp = ast_channel_alloc(0, state, 0, 0, "Agent/P%s-%d", p->agent, ast_random() & 0xffff); + tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/P%s-%d", p->agent, ast_random() & 0xffff); else - tmp = ast_channel_alloc(0, state, 0, 0, "Agent/%s", p->agent); + tmp = ast_channel_alloc(0, state, 0, 0, "", p->chan ? p->chan->exten:"", p->chan ? p->chan->context:"", 0, "Agent/%s", p->agent); if (!tmp) { ast_log(LOG_WARNING, "Unable to allocate agent channel structure\n"); return NULL; diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c index 2be93ef9f..aa444c5db 100644 --- a/channels/chan_alsa.c +++ b/channels/chan_alsa.c @@ -790,7 +790,7 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state) { struct ast_channel *tmp = NULL; - if (!(tmp = ast_channel_alloc(1, state, 0, 0, "ALSA/%s", indevname))) + if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "ALSA/%s", indevname))) return NULL; tmp->tech = &alsa_tech; diff --git a/channels/chan_features.c b/channels/chan_features.c index 2fb720780..09792700c 100644 --- a/channels/chan_features.c +++ b/channels/chan_features.c @@ -472,7 +472,7 @@ static struct ast_channel *features_new(struct feature_pvt *p, int state, int in if (y >= 3) break; } - tmp = ast_channel_alloc(0, state, 0,0, b2); + tmp = ast_channel_alloc(0, state, 0,0, "", "", "", 0, b2); /* free up the name, it was copied into the channel name */ if (b2) free(b2); diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c index bab6f9217..8c4a27bdb 100644 --- a/channels/chan_gtalk.c +++ b/channels/chan_gtalk.c @@ -904,7 +904,7 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, n2 = title; else n2 = i->us; - tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff); + tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, client->accountcode, i->exten, client->context, client->amaflags, "Gtalk/%s-%04lx", n2, ast_random() & 0xffff); if (!tmp) { ast_log(LOG_WARNING, "Unable to allocate Gtalk channel structure!\n"); return NULL; diff --git a/channels/chan_h323.c b/channels/chan_h323.c index 6ab4ab5e1..70725aca7 100644 --- a/channels/chan_h323.c +++ b/channels/chan_h323.c @@ -1024,7 +1024,7 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c /* Don't hold a oh323_pvt lock while we allocate a chanel */ ast_mutex_unlock(&pvt->lock); - ch = ast_channel_alloc(1, state, cid_num, cid_name, "H323/%s", host); + ch = ast_channel_alloc(1, state, cid_num, cid_name, pvt->accountcode, pvt->exten, pvt->context, pvt->amaflags, "H323/%s", host); /* Update usage counter */ ast_module_ref(ast_module_info->self); ast_mutex_lock(&pvt->lock); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index 2fa322f42..88e1ae58a 100644 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -3377,7 +3377,7 @@ static struct ast_channel *ast_iax2_new(int callno, int state, int capability) /* Don't hold call lock */ ast_mutex_unlock(&iaxsl[callno]); - tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "IAX2/%s-%d", i->host, i->callno); + tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "IAX2/%s-%d", i->host, i->callno); ast_mutex_lock(&iaxsl[callno]); if (!tmp) return NULL; @@ -6220,8 +6220,8 @@ static int iax_park(struct ast_channel *chan1, struct ast_channel *chan2) struct iax_dual *d; struct ast_channel *chan1m, *chan2m; pthread_t th; - chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Parking/%s", chan1->name); - chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "IAXPeer/%s",chan2->name); + chan1m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); + chan2m = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "IAXPeer/%s",chan2->name); if (chan2m && chan1m) { /* Make formats okay */ chan1m->readformat = chan1->readformat; diff --git a/channels/chan_local.c b/channels/chan_local.c index 265d685c8..15a38a693 100644 --- a/channels/chan_local.c +++ b/channels/chan_local.c @@ -584,8 +584,8 @@ static struct ast_channel *local_new(struct local_pvt *p, int state) int randnum = ast_random() & 0xffff, fmt = 0; /* Allocate two new Asterisk channels */ - if (!(tmp = ast_channel_alloc(1, state, 0, 0, "Local/%s@%s-%04x,1", p->exten, p->context, randnum)) - || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, "Local/%s@%s-%04x,2", p->exten, p->context, randnum))) { + if (!(tmp = ast_channel_alloc(1, state, 0, 0, "", p->exten, p->context, 0, "Local/%s@%s-%04x,1", p->exten, p->context, randnum)) + || !(tmp2 = ast_channel_alloc(1, AST_STATE_RING, 0, 0, "", p->exten, p->context, 0, "Local/%s@%s-%04x,2", p->exten, p->context, randnum))) { if (tmp) ast_channel_free(tmp); if (tmp2) diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c index acabdc7e4..27ca2688c 100644 --- a/channels/chan_mgcp.c +++ b/channels/chan_mgcp.c @@ -1433,7 +1433,7 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state) struct mgcp_endpoint *i = sub->parent; int fmt; - tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id); + tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id); if (tmp) { tmp->tech = &mgcp_tech; tmp->nativeformats = i->capability; diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c index fa13d0383..37aec6261 100644 --- a/channels/chan_misdn.c +++ b/channels/chan_misdn.c @@ -3167,7 +3167,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state, char if (callerid) ast_callerid_parse(callerid, &cid_name, &cid_num); - tmp = ast_channel_alloc(1, state, cid_num, cid_name, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); + tmp = ast_channel_alloc(1, state, cid_num, cid_name, "", exten, "", 0, "%s/%d-u%d", misdn_type, chan_offset + c, glob_channel++); if (tmp) { chan_misdn_log(2, 0, " --> * NEW CHANNEL dad:%s oad:%s\n",exten,callerid); diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c index 0e9a32950..2cb912e54 100644 --- a/channels/chan_nbs.c +++ b/channels/chan_nbs.c @@ -233,7 +233,7 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame) static struct ast_channel *nbs_new(struct nbs_pvt *i, int state) { struct ast_channel *tmp; - tmp = ast_channel_alloc(1, state, 0, 0, "NBS/%s", i->stream); + tmp = ast_channel_alloc(1, state, 0, 0, "", "s", context, 0, "NBS/%s", i->stream); if (tmp) { tmp->tech = &nbs_tech; tmp->fds[0] = nbs_fd(i->nbs); diff --git a/channels/chan_oss.c b/channels/chan_oss.c index d6757a636..d7344961d 100644 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -1021,7 +1021,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, { struct ast_channel *c; - c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "OSS/%s", o->device + 5); + c = ast_channel_alloc(1, state, o->cid_num, o->cid_name, "", o->ext, o->ctx, 0, "OSS/%s", o->device + 5); if (c == NULL) return NULL; c->tech = &oss_tech; @@ -1033,10 +1033,6 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, c->writeformat = AST_FORMAT_SLINEAR; c->tech_pvt = o; - if (!ast_strlen_zero(ctx)) - ast_copy_string(c->context, ctx, sizeof(c->context)); - if (!ast_strlen_zero(ext)) - ast_copy_string(c->exten, ext, sizeof(c->exten)); if (!ast_strlen_zero(o->language)) ast_string_field_set(c, language, o->language); /* Don't use ast_set_callerid() here because it will diff --git a/channels/chan_phone.c b/channels/chan_phone.c index 8312fabf0..76311fc56 100644 --- a/channels/chan_phone.c +++ b/channels/chan_phone.c @@ -865,7 +865,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *conte { struct ast_channel *tmp; struct phone_codec_data codec; - tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "Phone/%s", i->dev + 5); + tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, 0, "Phone/%s", i->dev + 5); if (tmp) { tmp->tech = cur_tech; tmp->fds[0] = i->fd; diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 5c3cac5f5..dd363276e 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -4091,8 +4091,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit sip_pvt_unlock(i); /* Don't hold a sip pvt lock while we allocate a channel */ - - tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "SIP/%s-%08x", my_name, (int)(long) i); + tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, i->accountcode, i->exten, i->context, i->amaflags, "SIP/%s-%08x", my_name, (int)(long) i); } if (!tmp) { @@ -4207,6 +4206,7 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit ast_copy_string(tmp->context, i->context, sizeof(tmp->context)); ast_copy_string(tmp->exten, i->exten, sizeof(tmp->exten)); + /* Don't use ast_set_callerid() here because it will * generate an unnecessary NewCallerID event */ tmp->cid.cid_num = ast_strdup(i->cid_num); @@ -13302,8 +13302,8 @@ static int sip_park(struct ast_channel *chan1, struct ast_channel *chan2, struct /* Chan2m: The transferer, chan1m: The transferee */ pthread_t th; - transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Parking/%s", chan1->name); - transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "SIPPeer/%s", chan2->name); + transferee = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan1->accountcode, chan1->exten, chan1->context, chan1->amaflags, "Parking/%s", chan1->name); + transferer = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan2->accountcode, chan2->exten, chan2->context, chan2->amaflags, "SIPPeer/%s", chan2->name); if ((!transferer) || (!transferee)) { if (transferee) { transferee->hangupcause = AST_CAUSE_SWITCH_CONGESTION; @@ -14116,7 +14116,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int /* Initialize our tag */ make_our_tag(p->tag, sizeof(p->tag)); - /* First invitation - create the channel */ c = sip_new(p, AST_STATE_DOWN, S_OR(p->username, NULL)); *recount = 1; diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c index 8d88f8583..f06db4d58 100644 --- a/channels/chan_skinny.c +++ b/channels/chan_skinny.c @@ -2810,7 +2810,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state) struct skinny_device *d = l->parent; int fmt; - tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, "Skinny/%s@%s-%d", l->name, d->name, callnums); + tmp = ast_channel_alloc(1, state, l->cid_num, l->cid_name, l->accountcode, l->exten, l->context, l->amaflags, "Skinny/%s@%s-%d", l->name, d->name, callnums); if (!tmp) { ast_log(LOG_WARNING, "Unable to allocate channel structure\n"); return NULL; diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc index e85500b93..ddee75d99 100644 --- a/channels/chan_vpb.cc +++ b/channels/chan_vpb.cc @@ -2626,7 +2626,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st if (option_verbose > 3) ast_verbose("%s: New call for context [%s]\n",me->dev,context); - tmp = ast_channel_alloc(1, state, 0, 0, me->dev); + tmp = ast_channel_alloc(1, state, 0, 0, "", me->exten, me->context, 0, me->dev); if (tmp) { if (use_ast_ind == 1){ tmp->tech = &vpb_tech_indicate; diff --git a/channels/chan_zap.c b/channels/chan_zap.c index 6479311e7..0aa37a8b8 100644 --- a/channels/chan_zap.c +++ b/channels/chan_zap.c @@ -5520,7 +5520,7 @@ static struct ast_channel *zt_new(struct zt_pvt *i, int state, int startpbx, int } y++; } while (x < 3); - tmp = ast_channel_alloc(0, state, 0, 0, b2); + tmp = ast_channel_alloc(0, state, 0, 0, i->accountcode, i->exten, i->context, i->amaflags, b2); if (b2) /*!> b2 can be freed now, it's been copied into the channel structure */ free(b2); if (!tmp) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 1f7f3934a..6fa71ad11 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -633,7 +633,7 @@ int ast_setstate(struct ast_channel *chan, enum ast_channel_state); by default set to the "default" context and extension "s" */ -struct ast_channel *ast_channel_alloc(int needalertpipe, int state, const char *cid_num, const char *cid_name, const char *name_fmt, ...); +struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...); /*! \brief Queue an outgoing frame */ int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f); diff --git a/main/cdr.c b/main/cdr.c index be2385212..7703e35a5 100644 --- a/main/cdr.c +++ b/main/cdr.c @@ -77,7 +77,7 @@ static struct ast_cdr_batch { int size; struct ast_cdr_batch_item *head; struct ast_cdr_batch_item *tail; -} *batch; +} *batch = NULL; static struct sched_context *sched; static int cdr_sched = -1; @@ -474,31 +474,80 @@ struct ast_cdr *ast_cdr_alloc(void) return x; } +static void cdr_merge_vars(struct ast_cdr *to, struct ast_cdr *from) +{ + struct ast_var_t *variablesfrom,*variablesto; + struct varshead *headpfrom = &to->varshead; + struct varshead *headpto = &from->varshead; + AST_LIST_TRAVERSE_SAFE_BEGIN(headpfrom, variablesfrom, entries) { + /* for every var in from, stick it in to */ + const char *fromvarname, *fromvarval; + const char *tovarname, *tovarval; + fromvarname = ast_var_name(variablesfrom); + fromvarval = ast_var_value(variablesfrom); + tovarname = 0; + + /* now, quick see if that var is in the 'to' cdr already */ + AST_LIST_TRAVERSE(headpto, variablesto, entries) { + + /* now, quick see if that var is in the 'to' cdr already */ + if ( strcasecmp(fromvarname, ast_var_name(variablesto)) == 0 ) { + tovarname = ast_var_name(variablesto); + tovarval = ast_var_value(variablesto); + break; + } + } + if (tovarname && strcasecmp(fromvarval,tovarval) != 0) { /* this message here to see how irritating the userbase finds it */ + ast_log(LOG_NOTICE, "Merging CDR's: variable %s value %s dropped in favor of value %s\n", tovarname, fromvarval, tovarval); + continue; + } else if (tovarname && strcasecmp(fromvarval,tovarval) == 0) /* if they are the same, the job is done */ + continue; + + /*rip this var out of the from cdr, and stick it in the to cdr */ + AST_LIST_REMOVE_CURRENT(headpfrom, entries); + AST_LIST_INSERT_HEAD(headpto, variablesfrom, entries); + } + AST_LIST_TRAVERSE_SAFE_END; +} + void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from) { if (!to || !from) return; + if (!ast_tvzero(from->start)) { if (!ast_tvzero(to->start)) { if (ast_tvcmp(to->start, from->start) > 0 ) { to->start = from->start; /* use the earliest time */ from->start = ast_tv(0,0); /* we actively "steal" these values */ - } else { - ast_log(LOG_WARNING,"CDR start disagreement for %s\n", to->channel); } + /* else nothing to do */ } else { to->start = from->start; from->start = ast_tv(0,0); /* we actively "steal" these values */ } } + if (!ast_tvzero(from->answer)) { + if (!ast_tvzero(to->answer)) { + if (ast_tvcmp(to->answer, from->answer) > 0 ) { + to->answer = from->answer; /* use the earliest time */ + from->answer = ast_tv(0,0); /* we actively "steal" these values */ + } + /* we got the earliest answer time, so we'll settle for that? */ + } else { + to->answer = from->answer; + from->answer = ast_tv(0,0); /* we actively "steal" these values */ + } + } if (!ast_tvzero(from->end)) { if (!ast_tvzero(to->end)) { if (ast_tvcmp(to->end, from->end) < 0 ) { to->end = from->end; /* use the latest time */ from->end = ast_tv(0,0); /* we actively "steal" these values */ - } else { - ast_log(LOG_WARNING,"CDR end disagreement for %s\n", to->channel); + to->duration = to->end.tv_sec - to->start.tv_sec; /* don't forget to update the duration, billsec, when we set end */ + to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec; } + /* else, nothing to do */ } else { to->end = from->end; from->end = ast_tv(0,0); /* we actively "steal" these values */ @@ -506,19 +555,6 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from) to->billsec = ast_tvzero(to->answer) ? 0 : to->end.tv_sec - to->answer.tv_sec; } } - if (!ast_tvzero(from->answer)) { - if (!ast_tvzero(to->answer)) { - if (ast_tvcmp(to->answer, from->answer) > 0 ) { - to->answer = from->answer; /* use the earliest time */ - from->answer = ast_tv(0,0); /* we actively "steal" these values */ - } else { - ast_log(LOG_WARNING,"CDR answer disagreement for %s\n", to->channel); - } - } else { - to->answer = from->answer; - from->answer = ast_tv(0,0); /* we actively "steal" these values */ - } - } if (to->disposition < from->disposition) { to->disposition = from->disposition; from->disposition = AST_CDR_NOANSWER; @@ -564,6 +600,18 @@ void ast_cdr_merge(struct ast_cdr *to, struct ast_cdr *from) from->userfield[0] = 0; /* theft */ } /* flags, varsead, ? */ + cdr_merge_vars(from, to); + + if (ast_test_flag(from, AST_CDR_FLAG_KEEP_VARS)) + ast_set_flag(to, AST_CDR_FLAG_KEEP_VARS); + if (ast_test_flag(from, AST_CDR_FLAG_POSTED)) + ast_set_flag(to, AST_CDR_FLAG_POSTED); + if (ast_test_flag(from, AST_CDR_FLAG_LOCKED)) + ast_set_flag(to, AST_CDR_FLAG_LOCKED); + if (ast_test_flag(from, AST_CDR_FLAG_CHILD)) + ast_set_flag(to, AST_CDR_FLAG_CHILD); + if (ast_test_flag(from, AST_CDR_FLAG_POST_DISABLED)) + ast_set_flag(to, AST_CDR_FLAG_POST_DISABLED); } void ast_cdr_start(struct ast_cdr *cdr) diff --git a/main/channel.c b/main/channel.c index 998843d7e..87be422a7 100644 --- a/main/channel.c +++ b/main/channel.c @@ -620,7 +620,7 @@ static const struct ast_channel_tech null_tech = { }; /*! \brief Create a new channel structure */ -struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *name_fmt, ...) +struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_num, const char *cid_name, const char *acctcode, const char *exten, const char *context, const int amaflag, const char *name_fmt, ...) { struct ast_channel *tmp; int x; @@ -733,6 +733,30 @@ struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_ } /* Reminder for the future: under what conditions do we NOT want to track cdrs on channels? */ + + /* These 4 variables need to be set up for the cdr_init() to work right */ + if (amaflag) + tmp->amaflags = amaflag; + else + tmp->amaflags = ast_default_amaflags; + + if (!ast_strlen_zero(acctcode)) + ast_string_field_set(tmp, accountcode, acctcode); + else + ast_string_field_set(tmp, accountcode, ast_default_accountcode); + + if (!ast_strlen_zero(context)) + ast_copy_string(tmp->context, context, sizeof(tmp->context)); + else + strcpy(tmp->context, "default"); + + if (!ast_strlen_zero(exten)) + ast_copy_string(tmp->exten, exten, sizeof(tmp->exten)); + else + strcpy(tmp->exten, "s"); + + tmp->priority = 1; + tmp->cdr = ast_cdr_alloc(); ast_cdr_init(tmp->cdr, tmp); ast_cdr_start(tmp->cdr); @@ -744,13 +768,7 @@ struct ast_channel *ast_channel_alloc(int needqueue, int state, const char *cid_ AST_LIST_HEAD_INIT_NOLOCK(&tmp->datastores); - strcpy(tmp->context, "default"); - strcpy(tmp->exten, "s"); - tmp->priority = 1; - ast_string_field_set(tmp, language, defaultlanguage); - tmp->amaflags = ast_default_amaflags; - ast_string_field_set(tmp, accountcode, ast_default_accountcode); tmp->tech = &null_tech; diff --git a/main/pbx.c b/main/pbx.c index 2ce76054d..ef9567850 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -4573,7 +4573,7 @@ int ast_async_goto(struct ast_channel *chan, const char *context, const char *ex /* In order to do it when the channel doesn't really exist within the PBX, we have to make a new channel, masquerade, and start the PBX at the new location */ - struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, "AsyncGoto/%s", chan->name); + struct ast_channel *tmpchan = ast_channel_alloc(0, chan->_state, 0, 0, chan->accountcode, chan->exten, chan->context, chan->amaflags, "AsyncGoto/%s", chan->name); if (chan->cdr) { tmpchan->cdr = ast_cdr_dup(chan->cdr); } @@ -4934,7 +4934,7 @@ static void *async_wait(void *data) static int ast_pbx_outgoing_cdr_failed(void) { /* allocate a channel */ - struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, 0); + struct ast_channel *chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, 0); if (!chan) return -1; /* failure */ @@ -5053,7 +5053,7 @@ int ast_pbx_outgoing_exten(const char *type, int format, void *data, int timeout /* create a fake channel and execute the "failed" extension (if it exists) within the requested context */ /* check if "failed" exists */ if (ast_exists_extension(chan, context, "failed", 1, NULL)) { - chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "OutgoingSpoolFailed"); + chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "OutgoingSpoolFailed"); if (chan) { if (!ast_strlen_zero(context)) ast_copy_string(chan->context, context, sizeof(chan->context)); diff --git a/res/res_features.c b/res/res_features.c index 60b2f0384..18e221888 100644 --- a/res/res_features.c +++ b/res/res_features.c @@ -194,7 +194,7 @@ static void check_goto_on_transfer(struct ast_channel *chan) goto_on_transfer = ast_strdupa(val); - if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, chan->name))) + if (!(xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, chan->name))) return; for (x = goto_on_transfer; x && *x; x++) { @@ -445,7 +445,7 @@ int ast_masq_park_call(struct ast_channel *rchan, struct ast_channel *peer, int struct ast_frame *f; /* Make a new, fake channel that we'll use to masquerade in the real one */ - if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Parked/%s",rchan->name))) { + if (!(chan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, rchan->accountcode, rchan->exten, rchan->context, rchan->amaflags, "Parked/%s",rchan->name))) { ast_log(LOG_WARNING, "Unable to create parked channel\n"); return -1; } @@ -840,7 +840,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st return -1; } - xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "Transfered/%s", transferee->name); + xferchan = ast_channel_alloc(0, AST_STATE_DOWN, 0, 0, "", "", "", 0, "Transfered/%s", transferee->name); if (!xferchan) { ast_hangup(newchan); return -1; @@ -1373,81 +1373,6 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast peer->cdr = NULL; } - /* arrange the cdrs */ - bridge_cdr = ast_cdr_alloc(); - if (bridge_cdr) { - if (chan->cdr && peer->cdr) { /* both of them? merge */ - ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the destination as a base, but, really, it's random */ - ast_cdr_start(bridge_cdr); /* now is the time to start */ - /* absorb the channel cdr */ - ast_cdr_merge(bridge_cdr, chan->cdr); - ast_cdr_discard(chan->cdr); /* no posting these guys */ - chan->cdr = NULL; - - /* absorb the peer cdr */ - ast_cdr_merge(bridge_cdr, peer->cdr); - ast_cdr_discard(peer->cdr); /* no posting these guys */ - peer->cdr = NULL; - } else if (chan->cdr) { - /* take the cdr from the channel - literally */ - ast_cdr_init(bridge_cdr,chan); - if (chan->cdr->disposition!=AST_CDR_ANSWERED) { - ast_cdr_end(chan->cdr); - ast_cdr_detach(chan->cdr); /* post the existing cdr, we will be starting a fresh new cdr presently */ - chan->cdr = ast_cdr_alloc(); - if (chan->cdr) { - ast_cdr_init(chan->cdr,chan); /* a fresh new one its place */ - ast_cdr_start(chan->cdr); /* now is the time to start */ - } - } else { - /* absorb this data */ - ast_cdr_merge(bridge_cdr, chan->cdr); - ast_cdr_discard(chan->cdr); /* no posting these guys */ - chan->cdr = NULL; - } - peer->cdr = ast_cdr_alloc(); - if (peer->cdr) - ast_cdr_init(peer->cdr, peer); - } else if (peer->cdr) { - /* take the cdr from the peer - literally */ - ast_cdr_init(bridge_cdr,peer); - if (peer->cdr->disposition != AST_CDR_ANSWERED) { - ast_cdr_end(peer->cdr); - ast_cdr_detach(peer->cdr); /* post the existing cdr, we will be starting a fresh new cdr presently */ - peer->cdr = ast_cdr_alloc(); - if (peer->cdr) { - ast_cdr_init(peer->cdr,peer); /* a fresh new one its place */ - ast_cdr_start(peer->cdr); /* now is the time to start */ - } - } else { - /* absorb this data */ - ast_cdr_merge(bridge_cdr, chan->cdr); - ast_cdr_discard(chan->cdr); /* no posting these guys */ - chan->cdr = NULL; - } - chan->cdr = ast_cdr_alloc(); - if (chan->cdr) - ast_cdr_init(chan->cdr, chan); - } else { - /* make up a new cdr */ - ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */ - chan->cdr = ast_cdr_alloc(); - if (chan->cdr) { - ast_cdr_init(chan->cdr, chan); - } - peer->cdr = ast_cdr_alloc(); - if (chan->cdr) { - ast_cdr_init(peer->cdr, peer); - ast_cdr_start(peer->cdr); /* now is the time to start */ - } - } - if (ast_strlen_zero(bridge_cdr->dstchannel)) { - if (strcmp(bridge_cdr->channel, peer->name) != 0) - ast_cdr_setdestchan(bridge_cdr, peer->name); - else - ast_cdr_setdestchan(bridge_cdr, chan->name); - } - } for (;;) { struct ast_channel *other; /* used later */ @@ -1514,19 +1439,6 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } if (res < 0) { ast_log(LOG_WARNING, "Bridge failed on channels %s and %s\n", chan->name, peer->name); - /* whoa!! don't go running off without cleaning up your mess! */ - if (bridge_cdr) { - ast_cdr_merge(bridge_cdr,chan->cdr); - ast_cdr_merge(bridge_cdr,peer->cdr); - ast_cdr_failed(bridge_cdr); - ast_cdr_end(bridge_cdr); - ast_cdr_detach(bridge_cdr); - bridge_cdr = NULL; - } - ast_cdr_free(chan->cdr); /* no posting these guys */ - ast_cdr_free(peer->cdr); - chan->cdr = NULL; - peer->cdr = NULL; return -1; } @@ -1615,20 +1527,51 @@ int ast_bridge_call(struct ast_channel *chan,struct ast_channel *peer,struct ast } if (f) ast_frfree(f); + } - /* before leaving, post the cdr we accumulated */ - /* whoa!! don't go running off without cleaning up your mess! */ + /* arrange the cdrs */ + bridge_cdr = ast_cdr_alloc(); if (bridge_cdr) { - ast_cdr_merge(bridge_cdr,chan->cdr); - ast_cdr_merge(bridge_cdr,peer->cdr); - ast_cdr_end(bridge_cdr); - ast_cdr_detach(bridge_cdr); - bridge_cdr = NULL; - } - ast_cdr_discard(chan->cdr); /* no posting these guys */ - ast_cdr_discard(peer->cdr); - chan->cdr = NULL; - peer->cdr = NULL; + if (chan->cdr && peer->cdr) { /* both of them? merge */ + ast_cdr_init(bridge_cdr,chan); /* seems more logicaller to use the destination as a base, but, really, it's random */ + ast_cdr_start(bridge_cdr); /* now is the time to start */ + + /* absorb the channel cdr */ + ast_cdr_merge(bridge_cdr, chan->cdr); + ast_cdr_discard(chan->cdr); /* no posting these guys */ + + /* absorb the peer cdr */ + ast_cdr_merge(bridge_cdr, peer->cdr); + ast_cdr_discard(peer->cdr); /* no posting these guys */ + peer->cdr = NULL; + chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */ + } else if (chan->cdr) { + /* take the cdr from the channel - literally */ + ast_cdr_init(bridge_cdr,chan); + /* absorb this data */ + ast_cdr_merge(bridge_cdr, chan->cdr); + ast_cdr_discard(chan->cdr); /* no posting these guys */ + chan->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */ + } else if (peer->cdr) { + /* take the cdr from the peer - literally */ + ast_cdr_init(bridge_cdr,peer); + /* absorb this data */ + ast_cdr_merge(bridge_cdr, peer->cdr); + ast_cdr_discard(peer->cdr); /* no posting these guys */ + peer->cdr = NULL; + peer->cdr = bridge_cdr; /* make this available to the rest of the world via the chan while the call is in progress */ + } else { + /* make up a new cdr */ + ast_cdr_init(bridge_cdr,chan); /* eh, just pick one of them */ + chan->cdr = bridge_cdr; /* */ + } + if (ast_strlen_zero(bridge_cdr->dstchannel)) { + if (strcmp(bridge_cdr->channel, peer->name) != 0) + ast_cdr_setdestchan(bridge_cdr, peer->name); + else + ast_cdr_setdestchan(bridge_cdr, chan->name); + } + } return res; } |