diff --git a/apps/Makefile b/apps/Makefile index 5aacce21f2d6bf74d7c178835445647e66bda488..ebd149c76abe52b9cbb7b242a62309e6d79832d4 100755 --- a/apps/Makefile +++ b/apps/Makefile @@ -29,7 +29,7 @@ APPS=app_dial.so app_playback.so app_voicemail.so app_directory.so app_mp3.so\ app_nbscat.so app_sendtext.so app_exec.so app_sms.so \ app_groupcount.so app_txtcidname.so app_controlplayback.so \ app_talkdetect.so app_alarmreceiver.so app_userevent.so app_verbose.so \ - app_test.so + app_test.so app_forkcdr.so ifneq (${OSARCH},Darwin) APPS+=app_intercom.so diff --git a/apps/app_forkcdr.c b/apps/app_forkcdr.c new file mode 100755 index 0000000000000000000000000000000000000000..547bfa45eae214270e8680b3dc1d380fefed9433 --- /dev/null +++ b/apps/app_forkcdr.c @@ -0,0 +1,89 @@ +/* + * Asterisk -- A telephony toolkit for Linux. + * + * Fork CDR application + * Copyright Anthony Minessale anthmct@yahoo.com + * Development of this app Sponsered/Funded by TAAN Softworks Corp + * + * This program is free software, distributed under the terms of + * the GNU General Public License + */ + +#include <asterisk/file.h> +#include <asterisk/logger.h> +#include <asterisk/channel.h> +#include <asterisk/pbx.h> +#include <asterisk/cdr.h> +#include <asterisk/module.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <pthread.h> + +static char *tdesc = "Fork The CDR into 2 seperate entities."; +static char *app = "ForkCDR"; +static char *synopsis = +"Forks the Call Data Record\n" +" ForkCDR(): Causes the Call Data Record to fork an additional\n" + "cdr record starting from the time of the fork call\n"; + + +STANDARD_LOCAL_USER; + +LOCAL_USER_DECL; + + +static void ast_cdr_clone(struct ast_cdr *cdr) { + struct ast_cdr *newcdr = ast_cdr_alloc(); + memcpy(newcdr,cdr,sizeof(struct ast_cdr)); + ast_cdr_append(cdr,newcdr); + gettimeofday(&newcdr->start, NULL); + memset(&newcdr->answer, 0, sizeof(newcdr->answer)); + ast_cdr_add_flag(cdr,AST_CDR_FLAG_CHILD|AST_CDR_FLAG_LOCKED); +} + +static void ast_cdr_fork(struct ast_channel *chan) { + if(chan && chan->cdr) { + ast_cdr_clone(chan->cdr); + } +} + +static int forkcdr_exec(struct ast_channel *chan, void *data) +{ + int res=0; + struct localuser *u; + LOCAL_USER_ADD(u); + + ast_cdr_fork(chan); + + LOCAL_USER_REMOVE(u); + return res; +} + +int unload_module(void) +{ + STANDARD_HANGUP_LOCALUSERS; + return ast_unregister_application(app); +} + +int load_module(void) +{ + return ast_register_application(app, forkcdr_exec, synopsis, tdesc); +} + +char *description(void) +{ + return tdesc; +} + +int usecount(void) +{ + int res; + STANDARD_USECOUNT(res); + return res; +} + +char *key() +{ + return ASTERISK_GPL_KEY; +} diff --git a/cdr.c b/cdr.c index 8057fa1aa80bc5da77d54f7c9ec4dd922d95a774..f4e97efcec337e8ec0554535e886371f1fd4500c 100755 --- a/cdr.c +++ b/cdr.c @@ -499,25 +499,29 @@ void ast_cdr_post(struct ast_cdr *cdr) } } -void ast_cdr_reset(struct ast_cdr *cdr, int post) +void ast_cdr_reset(struct ast_cdr *cdr, int flags) { while (cdr) { /* Post if requested */ - if (post) { - ast_cdr_end(cdr); - ast_cdr_post(cdr); + if (ast_cdr_compare_flag(flags,AST_CDR_FLAG_LOCKED) || !ast_cdr_has_flag(cdr,AST_CDR_FLAG_LOCKED)) { + if (ast_cdr_compare_flag(flags,AST_CDR_FLAG_POSTED)) { + ast_cdr_end(cdr); + ast_cdr_post(cdr); + } + /* Reset to initial state */ + cdr->flags=0; + memset(&cdr->start, 0, sizeof(cdr->start)); + memset(&cdr->end, 0, sizeof(cdr->end)); + memset(&cdr->answer, 0, sizeof(cdr->answer)); + cdr->billsec = 0; + cdr->duration = 0; + ast_cdr_start(cdr); + cdr->disposition = AST_CDR_NOANSWER; } - /* Reset to initial state */ - cdr->flags=0; - memset(&cdr->start, 0, sizeof(cdr->start)); - memset(&cdr->end, 0, sizeof(cdr->end)); - memset(&cdr->answer, 0, sizeof(cdr->answer)); - cdr->billsec = 0; - cdr->duration = 0; - ast_cdr_start(cdr); - cdr->disposition = AST_CDR_NOANSWER; + cdr = cdr->next; } + } void ast_cdr_append(struct ast_cdr *cdr, struct ast_cdr *newcdr) { diff --git a/include/asterisk/cdr.h b/include/asterisk/cdr.h index 05d50664d3d50cc810636841189b5728110f44b7..90d9433e3e213474d7855146499a9fd7ee3211e7 100755 --- a/include/asterisk/cdr.h +++ b/include/asterisk/cdr.h @@ -220,9 +220,10 @@ extern char *ast_cdr_disp2str(int disposition); //! Reset the detail record, optionally posting it first /*! * \param cdr which cdr to act upon - * \param post whether or not to post the cdr first before resetting it + * \param flags |AST_CDR_FLAG_POSTED whether or not to post the cdr first before resetting it + * |AST_CDR_FLAG_LOCKED whether or not to reset locked CDR's */ -extern void ast_cdr_reset(struct ast_cdr *cdr, int post); +extern void ast_cdr_reset(struct ast_cdr *cdr, int flags); //! Flags to a string /*! @@ -248,6 +249,7 @@ extern int ast_default_amaflags; extern char ast_default_accountcode[20]; +#define ast_cdr_compare_flag(flags, flag) (flags & (flag)) #define ast_cdr_has_flag(cdr, flag) ((cdr)->flags & (flag)) #define ast_cdr_add_flag(cdr, flag) ((cdr)->flags |= (flag)) #define ast_cdr_del_flag(cdr, flag) ((cdr)->flags &= ~(flag)) diff --git a/pbx.c b/pbx.c index 2bc05ff5d9b4d696aab47e54fa69a49f377260eb..16888bdbfdac6a1a9b68012a058e6217883f7ab5 100755 --- a/pbx.c +++ b/pbx.c @@ -4387,11 +4387,16 @@ static int pbx_builtin_setlanguage(struct ast_channel *chan, void *data) static int pbx_builtin_resetcdr(struct ast_channel *chan, void *data) { + int flags = 0; /* Reset the CDR as specified */ - if (data) - ast_cdr_reset(chan->cdr, strchr((char *)data, 'w') ? 1 : 0); - else - ast_cdr_reset(chan->cdr, 0); + if(data) { + if(strchr((char *)data, 'w')) + flags |= AST_CDR_FLAG_POSTED; + if(strchr((char *)data, 'a')) + flags |= AST_CDR_FLAG_LOCKED; + } + + ast_cdr_reset(chan->cdr, flags); return 0; }