Mon Jul 14 17:24:47 2008

Asterisk developer's documentation


app_forkcdr.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Anthony Minessale anthmct@yahoo.com
00005  * Development of this app Sponsered/Funded  by TAAN Softworks Corp
00006  *
00007  * See http://www.asterisk.org for more information about
00008  * the Asterisk project. Please do not directly contact
00009  * any of the maintainers of this project for assistance;
00010  * the project provides a web site, mailing lists and IRC
00011  * channels for your use.
00012  *
00013  * This program is free software, distributed under the terms of
00014  * the GNU General Public License Version 2. See the LICENSE file
00015  * at the top of the source tree.
00016  */
00017 
00018 /*! \file
00019  *
00020  * \brief Fork CDR application
00021  *
00022  * \author Anthony Minessale anthmct@yahoo.com
00023  *
00024  * \note Development of this app Sponsored/Funded by TAAN Softworks Corp
00025  * 
00026  * \ingroup applications
00027  */
00028 
00029 #include "asterisk.h"
00030 
00031 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 118858 $")
00032 
00033 #include <stdlib.h>
00034 #include <stdio.h>
00035 #include <string.h>
00036 #include <unistd.h>
00037 
00038 #include "asterisk/file.h"
00039 #include "asterisk/logger.h"
00040 #include "asterisk/channel.h"
00041 #include "asterisk/pbx.h"
00042 #include "asterisk/cdr.h"
00043 #include "asterisk/app.h"
00044 #include "asterisk/module.h"
00045 
00046 static char *app = "ForkCDR";
00047 static char *synopsis = 
00048 "Forks the Call Data Record";
00049 static char *descrip = 
00050 "  ForkCDR([options]):  Causes the Call Data Record to fork an additional\n"
00051 "cdr record starting from the time of the fork call\n"
00052 "  Options:\n"
00053 "    a  - update the answer time on the NEW CDR just after it's been inited..\n"
00054 "         The new CDR may have been answered already, the reset that forkcdr.\n"
00055 "         does will erase the answer time. This will bring it back, but.\n"
00056 "         the answer time will be a copy of the fork/start time. It will.\n"
00057 "         only do this if the initial cdr was indeed already answered..\n"
00058 "    D -  Copy the disposition forward from the old cdr, after the .\n"
00059 "         init..\n"
00060 "    d -  Clear the dstchannel on the new CDR after reset..\n"
00061 "    e -  end the original CDR. Do this after all the necc. data.\n"
00062 "         is copied from the original CDR to the new forked CDR..\n"
00063 "    R -  do NOT reset the new cdr..\n"
00064 "    s(name=val) - Set the CDR var 'name' in the original CDR, with value.\n"
00065 "                  'val'.\n"
00066 "    v  - When the new CDR is forked, it gets a copy of the vars attached\n"
00067 "         to the current CDR. The vars attached to the original CDR are removed\n"
00068 "         unless this option is specified.\n";
00069 
00070 
00071 enum {
00072    OPT_SETANS =            (1 << 0),
00073    OPT_SETDISP =           (1 << 1),
00074    OPT_RESETDEST =         (1 << 2),
00075    OPT_ENDCDR =            (1 << 3),
00076    OPT_NORESET =           (1 << 4),
00077    OPT_KEEPVARS =          (1 << 5),
00078    OPT_VARSET =            (1 << 6),
00079 };
00080 
00081 enum {
00082    OPT_ARG_VARSET = 0,
00083    /* note: this entry _MUST_ be the last one in the enum */
00084    OPT_ARG_ARRAY_SIZE,
00085 };
00086 
00087 AST_APP_OPTIONS(forkcdr_exec_options, {
00088    AST_APP_OPTION('a', OPT_SETANS),
00089    AST_APP_OPTION('d', OPT_SETDISP),
00090    AST_APP_OPTION('D', OPT_RESETDEST),
00091    AST_APP_OPTION('e', OPT_ENDCDR),
00092    AST_APP_OPTION('R', OPT_NORESET),
00093    AST_APP_OPTION_ARG('s', OPT_VARSET, OPT_ARG_VARSET),
00094    AST_APP_OPTION('v', OPT_KEEPVARS),
00095 });
00096 
00097 static void ast_cdr_fork(struct ast_channel *chan, struct ast_flags optflags, char *set) 
00098 {
00099    struct ast_cdr *cdr;
00100    struct ast_cdr *newcdr;
00101    struct ast_flags flags = { AST_CDR_FLAG_KEEP_VARS };
00102 
00103    cdr = chan->cdr;
00104 
00105    while (cdr->next)
00106       cdr = cdr->next;
00107    
00108    if (!(newcdr = ast_cdr_dup(cdr)))
00109       return;
00110    
00111    ast_cdr_append(cdr, newcdr);
00112 
00113    if (!ast_test_flag(&optflags, OPT_NORESET))
00114       ast_cdr_reset(newcdr, &flags);
00115       
00116    if (!ast_test_flag(cdr, AST_CDR_FLAG_KEEP_VARS))
00117       ast_cdr_free_vars(cdr, 0);
00118    
00119    if (!ast_strlen_zero(set)) {
00120       char *varname = ast_strdupa(set), *varval;
00121       varval = strchr(varname,'=');
00122       if (varval) {
00123          *varval = 0;
00124          varval++;
00125          ast_cdr_setvar(cdr, varname, varval, 0);
00126       }
00127    }
00128    
00129    if (ast_test_flag(&optflags, OPT_SETANS) && !ast_tvzero(cdr->answer))
00130       newcdr->answer = newcdr->start;
00131 
00132    if (ast_test_flag(&optflags, OPT_SETDISP))
00133       newcdr->disposition = cdr->disposition;
00134    
00135    if (ast_test_flag(&optflags, OPT_RESETDEST))
00136       newcdr->dstchannel[0] = 0;
00137    
00138    if (ast_test_flag(&optflags, OPT_ENDCDR))
00139       ast_cdr_end(cdr);
00140 
00141    ast_set_flag(cdr, AST_CDR_FLAG_CHILD | AST_CDR_FLAG_LOCKED);
00142 }
00143 
00144 static int forkcdr_exec(struct ast_channel *chan, void *data)
00145 {
00146    int res = 0;
00147    struct ast_module_user *u;
00148    char *argcopy = NULL;
00149    struct ast_flags flags = {0};
00150    char *opts[OPT_ARG_ARRAY_SIZE];
00151    AST_DECLARE_APP_ARGS(arglist,
00152       AST_APP_ARG(options);
00153    );
00154 
00155    if (!chan->cdr) {
00156       ast_log(LOG_WARNING, "Channel does not have a CDR\n");
00157       return 0;
00158    }
00159 
00160    u = ast_module_user_add(chan);
00161 
00162    argcopy = ast_strdupa(data);
00163 
00164    AST_STANDARD_APP_ARGS(arglist, argcopy);
00165 
00166    if (!ast_strlen_zero(arglist.options)) {
00167       ast_app_parse_options(forkcdr_exec_options, &flags, opts, arglist.options);
00168    } else
00169       opts[OPT_ARG_VARSET] = 0;
00170    
00171    if (!ast_strlen_zero(data))
00172       ast_set2_flag(chan->cdr, ast_test_flag(&flags, OPT_KEEPVARS), AST_CDR_FLAG_KEEP_VARS);
00173    
00174    ast_cdr_fork(chan, flags, opts[OPT_ARG_VARSET]);
00175 
00176    ast_module_user_remove(u);
00177    return res;
00178 }
00179 
00180 static int unload_module(void)
00181 {
00182    int res;
00183 
00184    res = ast_unregister_application(app);
00185 
00186    ast_module_user_hangup_all();
00187 
00188    return res; 
00189 }
00190 
00191 static int load_module(void)
00192 {
00193    return ast_register_application(app, forkcdr_exec, synopsis, descrip);
00194 }
00195 
00196 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Fork The CDR into 2 separate entities");

Generated on Mon Jul 14 17:24:47 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1