static void ast_cdr_fork(struct ast_channel *chan, struct ast_flags optflags, char *set) { struct ast_cdr *cdr; struct ast_cdr *newcdr; struct ast_flags flags = { AST_CDR_FLAG_KEEP_VARS }; cdr = chan->cdr; while (cdr->next) cdr = cdr->next; if (!(newcdr = ast_cdr_dup(cdr))) return; ast_cdr_append(cdr, newcdr); if (!ast_test_flag(&optflags, OPT_NORESET)) ast_cdr_reset(newcdr, &flags); if (!ast_test_flag(cdr, AST_CDR_FLAG_KEEP_VARS)) ast_cdr_free_vars(cdr, 0); if (!ast_strlen_zero(set)) { char *varname = ast_strdupa(set), *varval; varval = strchr(varname,'='); if (varval) { *varval = 0; varval++; ast_cdr_setvar(cdr, varname, varval, 0); } } if (ast_test_flag(&optflags, OPT_SETANS) && !ast_tvzero(cdr->answer)) newcdr->answer = newcdr->start; if (ast_test_flag(&optflags, OPT_SETDISP)) newcdr->disposition = cdr->disposition; if (ast_test_flag(&optflags, OPT_RESETDEST)) newcdr->dstchannel[0] = 0; if (ast_test_flag(&optflags, OPT_ENDCDR)) ast_cdr_end(cdr); if (ast_test_flag(&optflags, OPT_ANSLOCK)) ast_set_flag(cdr, AST_CDR_FLAG_ANSLOCKED); if (ast_test_flag(&optflags, OPT_DONTOUCH)) ast_set_flag(cdr, AST_CDR_FLAG_DONT_TOUCH); ast_set_flag(cdr, AST_CDR_FLAG_CHILD | AST_CDR_FLAG_LOCKED); }
static int manager_log(struct ast_cdr *cdr) { struct ast_tm timeresult; char strStartTime[80] = ""; char strAnswerTime[80] = ""; char strEndTime[80] = ""; char buf[CUSTOM_FIELDS_BUF_SIZE]; if (!enablecdr) return 0; ast_localtime(&cdr->start, &timeresult, NULL); ast_strftime(strStartTime, sizeof(strStartTime), DATE_FORMAT, &timeresult); if (cdr->answer.tv_sec) { ast_localtime(&cdr->answer, &timeresult, NULL); ast_strftime(strAnswerTime, sizeof(strAnswerTime), DATE_FORMAT, &timeresult); } ast_localtime(&cdr->end, &timeresult, NULL); ast_strftime(strEndTime, sizeof(strEndTime), DATE_FORMAT, &timeresult); buf[0] = '\0'; ast_rwlock_rdlock(&customfields_lock); if (customfields && ast_str_strlen(customfields)) { struct ast_channel *dummy = ast_dummy_channel_alloc(); if (!dummy) { ast_log(LOG_ERROR, "Unable to allocate channel for variable substitution.\n"); return 0; } dummy->cdr = ast_cdr_dup(cdr); pbx_substitute_variables_helper(dummy, ast_str_buffer(customfields), buf, sizeof(buf) - 1); ast_channel_unref(dummy); } ast_rwlock_unlock(&customfields_lock); manager_event(EVENT_FLAG_CDR, "Cdr", "AccountCode: %s\r\n" "Source: %s\r\n" "Destination: %s\r\n" "DestinationContext: %s\r\n" "CallerID: %s\r\n" "Channel: %s\r\n" "DestinationChannel: %s\r\n" "LastApplication: %s\r\n" "LastData: %s\r\n" "StartTime: %s\r\n" "AnswerTime: %s\r\n" "EndTime: %s\r\n" "Duration: %ld\r\n" "BillableSeconds: %ld\r\n" "Disposition: %s\r\n" "AMAFlags: %s\r\n" "UniqueID: %s\r\n" "UserField: %s\r\n" "%s", cdr->accountcode, cdr->src, cdr->dst, cdr->dcontext, cdr->clid, cdr->channel, cdr->dstchannel, cdr->lastapp, cdr->lastdata, strStartTime, strAnswerTime, strEndTime, cdr->duration, cdr->billsec, ast_cdr_disp2str(cdr->disposition), ast_cdr_flags2str(cdr->amaflags), cdr->uniqueid, cdr->userfield,buf); return 0; }